Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by snapsL · Mar 04, 2018 at 06:39 PM · c#loopnull

foreach iteration variable.. null?

i hope i'm not missing something obvious here, but this is the first time i've truly been stumped with unity and actually had to come make my own post

there's nothing that crazy about this loop, but it didn't work as expected, and upon stepping through it, well.. how can h be null?

alt text

it also seems to completely step over certain lines within for no reason, i've no clue what's going on here. i've had bugs before with unity where it sort of loses its place among the lines of code, but restarting it/visual studio usually fixes things. this time, no dice

Comment
Add comment · Show 7
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image hexagonius · Mar 04, 2018 at 07:24 PM 0
Share

looks weird alright. what I notice is that you try to go without braces. Put em in properly and see if it fixed the issue. my guess is h is null because the first foreach is already done even though the syntax doesn't look like it.

avatar image snapsL hexagonius · Mar 04, 2018 at 07:45 PM 0
Share

no go, looks like lilius is right, very strange

avatar image Lilius · Mar 04, 2018 at 07:31 PM 0
Share

Just tested foreach, and it seems to do that and still works fine. It just kind of has a "warm up lap" :D . Have no Idea if it is supposed to be like that or what?

avatar image snapsL Lilius · Mar 04, 2018 at 07:37 PM 0
Share

yeah that's odd, never seen it in any other applications of c#, i guess i'll just try to roll with it, though the jumping around when i step through the lines is weirding me out a bit too. in the first and all other iterations it just completely skips over some lines when it clearly shouldn't

avatar image MacDx · Mar 05, 2018 at 05:11 PM 0
Share

I've seen this many times before, whenever I debug a foreach statement. When using a foreach, the value during the first "iteration" is always null (I put it between quotations because maybe it is not an actual iteration). Don't know exactly why, it most likely has to do with the inner workings of the statement and how C# handles it. $$anonymous$$y guess is that it first has to prepare the collection in some way to be able to go through it, thus the null value, since it hasn't started iterating at that point.

avatar image Hellium · Mar 05, 2018 at 05:24 PM 1
Share

I always use the standard for loop. A foreach loop tends to be less efficient (I know, it's a micro-optimization here), and I guess you may not have this problem with the for loop.

Note: Are you completely mad? You are using a goto? What's wrong with you? o.O

avatar image snapsL Hellium · Mar 05, 2018 at 05:29 PM 1
Share

hah! i see the standard boo-hiss reaction to goto is still going strong. this is one of the few legitimate uses in c# of a goto statement because it does not have a built in way to break out of multiple loops at once like php, for example (i.e. "break 2;")

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by Bunny83 · Mar 05, 2018 at 06:33 PM

Well, there could be several reasons why the debugger behaves strange "visually". First of all keep in mind that there is no "for" or "foreach" thing in the common intermediate language. Therefore what code results from a given for / foreach loop depends on the used compiler. Unity uses the Mono C# compiler while visual studio works on the basis of the .NET C# compiler. So those slight differences might result in this weird visual behaviour. Keep in mind that one line of highlevel code often belongs to several lines of IL code. So for a debugger to "step" through the highlevel code it has to know what statements / opcodes belong to the actual source code line.


One reason could be your goto statement. It breaks the usual construct of a foreach loop so VS might not even recognise the foreach properly. I suggest you have a look at the IL code that was generated by using ILSpy on your compiled assembly and switch the language to "IL" to see the "actual" code. The decompilation from IL to C# is usually quite good, however as i said a decompiler can only "assume" based on some opcode patterns what high level code has generated the given IL code.


While it's possible to omit the body brackets of loops and if statements if it only contains a single statement i strongly would recommend to only use this when the statement really is just a single line. Such a complex nested loop-->if-->loop is just confusing and it's easy to miss the exact flow. Code is mainly meant to be easy to write, read and understand by humans. Do not use certain techniques because it's shorter or quicker to write but because it actually improves readability.

Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Bunny83 · Mar 05, 2018 at 08:32 PM 0
Share

Aside from the "why does VisualStudio behave weird" the whole piece of code seems really strange. First of all the innermost if statement has the same condition as the if in the first loop, so it's redundant. $$anonymous$$ost likely you wanted to use "h2" ins$$anonymous$$d of "h". If that's the case all your code does is searching for the first two elements in that array / collection / whatever that are disabled. You seem to just pick the first element that is not null and assign "leader" as his leader. Furthermore you pick the second object that is disabled and make it follow the first one. That's all your code does.


Since both loops iterate over the same array obviously "h" (the first object) will be the first not enabled object in that array. Since your inner loop searches for an element with the same precondition but additionally it should be different from the first one, "h2" will be the next not enabled object after "h".


The same can be achieved with something like this:

 Character c1 = null;
 foreach(Character c in heros) {
     if (!c.Get<RoamController>().enabled) {
         if (c1 == null)
             c1 = c;
         else {
             c1.GetComponent<RoamFollower>().leader = leader;
             c.GetComponent<RoamFollower>().leader = c1;
             break;
         }
     }
 }

avatar image snapsL · Mar 05, 2018 at 10:06 PM 0
Share

that sounds likely, i do hope they make an attempt to clean things up a bit, especially now that they're moving so far in the .net direction

while i appreciate the attempt, your example isn't what it's intended to accomplish. this block of code on its own was quite literally the first thing i wrote down, and within the scope of this question, it's not meant to be anything other than my example of this behavior. it's clearly very messy, the 2 h references were indeed a typo, and the whole thing is easily debugged and cleaned up. nothing within should lead to some of the behaviors i was experiencing, even upon drilling deeper into the IL. also, i suggest taking a closer look; it's not a reasonable to suggest the goto would do anything out of the ordinary, given what's written there. it's a very simple break out of the loop once it reaches that line. at the point where we'd have to start questioning simple logic like that, unity would have made a big mistake somewhere in supporting visual studio in the first place

and yes, code is meant to be easy to read, which is why, outside of the confines of my day job where i do have to follow best practices, within my own little game project, i prefer to forego brackets, as i find what's written above less cluttered and easier to read than what you're suggesting :P

avatar image Bunny83 snapsL · Mar 06, 2018 at 12:18 AM 0
Share

Sorry but that doesn't have much to do with Unity. This is a Visual Studio issue. The debugger belongs completely to VS. As i said the problem might be that the VS debugger can't match the (jitted and) executing IL code with the actual C# code since VS would expect that the code was compiled with the .NET compiler which it probably wasn't.


Apart from that I've experienced some issues myself with plain .NET code. Especially generators / iterators (IEnumerator) can look really strange when debugging as the actual method that is executing looks completely different than the source code. You can find several people who noticed strange debugging experiences in plain .NET / VS like this, or this.


You haven't shown much context to your problem. If this code is in a coroutine or inside a NetworkBehaviour it's possible that the resulting IL looks completely different from what the source code shows. The UNetWeaver runs over the compiled assemblies and altering the code (though this only happens in NetworkBehaviours).


In the end just keep in $$anonymous$$d that it's not the highlevel code that is executed. Not even the IL code is executed since it's jit compiled to native code at runtime. If you have the profiler running in Unity there might be additional code injected which could trip up the debugger.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

459 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers

I dont know why im getting a null reference exception 1 Answer

Executing coroutines consecutively 0 Answers

Increase value through frames, or in a while? 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges