Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Who ritualistically uses the C# "var" keyword?

Discussion in 'Scripting' started by ArachnidAnimal, Apr 23, 2017.

  1. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,773
    It's not really practical to cache components in OnCollision* functions, given that it could be called for many different objects. What kind of witch-hunt is this?!
     
    glenneroo and Kiwasi like this.
  2. Deleted User

    Deleted User

    Guest

    I'm not sure he was being serious...
     
  3. labarilem

    labarilem

    Joined:
    Mar 4, 2017
    Posts:
    4
    Yes I was referring to the first use-case, should've been more explicit, sorry.
     
  4. ArachnidAnimal

    ArachnidAnimal

    Joined:
    Mar 3, 2015
    Posts:
    1,765
    I think in this example, the usage of "var" is poor.
    They have:
    var fire = c.GetComponent<Fire>();
    Nowhere here can you tell what type "Fire" is.
    Is it a script, a particle system, an audio source?
    You now have to hover over "Fire" to let the IDE tell you what Fire is.
    If you ask me, this usage is making it now harder to understand the code.
    To make it clearer they could have changed it from "var fire" to "var fireParticleSystem".
    Now it's clearer, but then you violate another rule: a variable name should not include its type.
    I like K&R only when I fully understand the code. When I'm trying to understand it, I prefer the Allman style.
     
  5. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,773
    Uh... what type is "Fire"? It's Fire. That's literally its type.

    If they wanted a particle system, it'd have to be
    var fire = c.GetComponent<ParticleSystem>();
    And... hey what do you know? I could tell by looking at the right half of that line that it wasn't a particle system!
     
    glenneroo, LaneFox, Ryiah and 3 others like this.
  6. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,514
    And saying:

    Fire fire = c.GetComponent<Fire>();

    Would give you no more information either. Var is not what is keeping you from knowing anything more than that 'fire' is of type 'Fire'.

    Well... it's definitely a Component, we know that. Again, var isn't keeping us from knowing anything else.

    Also, since ParticleSystem and AudioSource are both sealed classes, we know it's not those either.

    We can assume it's most likely a Script since the type isn't in UnityEngine namespace, but since it is a Component, it's most likely inheriting from MonoBehaviour and therefore a script.

    It COULD be an interface... but usually people name interfaces something like 'IFire'.

    You would have had to if var was used or not.

    How?

    OK, so the variable is named poorly in your opinion. Has nothing to do with 'var'.

    Furthermore... what if it IS a 'fire' script, as in flames.

    Especially since the following lines of code call a method called "NearHeat". As well as another script further down called 'smoke'.

    If it's a 'fire' script... then the name 'fire' is actually pretty good.

    Also...

    That's not a good rule honestly... anyways... you break that rule with 'fireParticleSystem' since if it were a ParticleSystem you've put the name of the type in the variable.

    You may be confusing a rule that exists in some circles that says a name of a variable shouldn't be the type name itself (not contain, but is the type name). Which technically 'fire' breaks. But again I find this rule to not be a good rule. It exists mostly in Java/C# enterprise development where classes get really obtuse names like FilePrintServerCallbackRelay... and yeah, the var being called filePrintServerCallbackRelay is probably a bad name for a variable. But hell, that's a bad name for a class too. It's just in enterprise software you often can't avoid horrible names like that. It's just the nature of the beast... so weird rules are invented to compensate for the chaos that ensues in a 10+ year old piece of software in constant maintenance cycles.

    It's up there with rules like 'one letter variable names are bad'.... yet we all use x,y,z,w,i,j,k all the freaking time! They're not referring to those uses though of course... they just mean don't be like:

    var a = new FilePrintServerCallbackRelay();



    Honestly... the only flaw I see in that code is that it says:
    float dist = 1 - ....

    I would have typed 1 as a float...
    float dist = 1f -

    But that's a minor quibble.

    ...

    I don't want to come off rude or mean or anything. But if that code is hard for you to read... it might not be the fault of the code. Faulkner can be difficult to read, but it's not Faulkner's fault... you just have to have the reading level needed. Practice makes perfect.
     
    Last edited: Apr 26, 2017
    Ryiah and KelsoMRK like this.
  7. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    It's a Fire. That's the only possible return type from GetComponent<Fire>().

    If you don't know how GetComponent works, you have no business calling yourself a Unity programmer.

    There are other cases where the return type is ambiguous and it might matter. But this is not one of them.
     
    glenneroo and lordofduct like this.
  8. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,992
    "var fire =" is so you don't need to understand types. It's the same reason unityscript encourages var w="cat";

    Most people start off knowing GetComponent takes the filename of one of your scripts. To save the link, write "var someName=" in front, just because. I've known some very good designer/artist/programmers who made beautiful games with just that bare minimum of understanding.

    It takes a while to realize that scripts even have types. Variables have types, so scripts are ... variables? That's not so obvious at first.
     
  9. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    I'm not a huge fine off the UnityScript way of using var. Back when UnityScript was popular, a significant portion of the questions on answers came down to new users not understanding typing. var was UnityScripts way of lying to new users and telling them not to bother learning types.

    var is for moderately competent coders. It's not, and it shouldn't ever be, a tool to let people avoid learning coding.
     
    StarManta likes this.
  10. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    I wholeheartedly disagree with this statement. Nothing about the fact that C# is a strongly typed language changes when a programmer uses the var keyword. If you use var to declare a string and an int and then try to compare the two it's going to fail and you're going to need to understand why. If you don't know how strong typing works then var isn't going to save you, but if you do then var does save you some rote typing. It's also absolutely necessary for anonymous LINQ types which I can guarantee beginner programmers are not going to tackle.
     
    glenneroo and Kiwasi like this.
  11. LaneFox

    LaneFox

    Joined:
    Jun 29, 2011
    Posts:
    7,462
    Here are some bad examples:
    Code (csharp):
    1.  
    2. var tempHelper = GetReference(); // coupled with bad naming, this is punishable by death. Twice, if necessary.
    3. var results = from x in item.Table select x;
    4. var reference1 = otherObject.MyProperty;
    5. var example = table.GetHelper();
    6. var value = 0;
    7. var val = 0.3f;
    8. var value = (float)GetValueOf(3);
    9. var weDontCareAboutOtherPeople = true;
    Here are some good use examples:
    Code (csharp):
    1. List<ComplicatedClassName> theList;
    2. <... stuff ...>
    3. public void FlattenTheList()
    4. {
    5.      foreach (var x in theList) { x = null; }
    6. }
    Code (csharp):
    1. var pathCache = new List<ClassNavigationPathConnector>();
    Code (csharp):
    1. var manager = Services.PlayerTracking[thisPlayerId].FetchInventory().ItemManager;
    Code (csharp):
    1. var character = ListOfNearbyChracters[index];
    Basically, if after reading the line of code that a var is used in then you have to ask "what is that var?" or continue to look at code to ascertain the type of the var then it is a bad application of var.

    Vars should only be used when it improves readability. Never because it would simply be convenient.
     
    StarManta likes this.
  12. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    I would disagree on the linq expression and the primitive value assignments because it's the same as a constructor. Look to the right - is the value an int; then var is in an int etc etc. (Although one could argue that var doesn't get you much mileage over int or bool but that's probably preference more than anything)

    LINQ is the weird case because it's evaluated when the expression is executed not when it's declared.
     
  13. LaneFox

    LaneFox

    Joined:
    Jun 29, 2011
    Posts:
    7,462
    The point of using var is to improve readability.

    Code (csharp):
    1. // this
    2. var temp0 = false;
    3. var temp1 = 0;
    4. var temp2 = 0f;
    5. var temp3 = "";
    6.  
    7. // versus this
    8. private bool temp0;
    9. private int temp1;
    10. private float temp2;
    11. private string temp3;
    12.  
    The use of var here is clearly impractical. The names are bad, and using var improves nothing. In fact, it is more difficult to read. This is why primitive var definitions are generally frowned upon - especially in the class scope. These sort of definitions could be tolerable for inner scope but it would greatly depend on the context and would be hard to convince someone that they are indeed an improvement over explicit definitions.
     
    Last edited: Apr 27, 2017
  14. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    It's a philosophical argument at the end of the day. Generally speaking I don't def at the class level using var either but I don't know that you could win an argument that doing so hurts readability universally. Being as explicit as possible is certainly your prerogative but ultimately that's where the argument ends. For example - even though I don't use var at the class level I also don't explicitly mark stuff as private because members are implicitly private. Sure it makes things "clearer" and "more readable" (which I think what you really mean is "more explicit") but at the end of the day I know that the default access level is private and if you want to work for me and you don't know that the default access level is private then you're not going to work for me. That's an organizational decision; so I don't know that it's appropriate in threads like this which are more about programming as a pure craft.

    Also - to be fair, crap naming is crap naming regardless of whether you use var or not. If I'm 300 lines down in that class and I come across temp0 then I still have to hover over it to see what the hell it is.

    In short - those examples are functionally identical and if you know that they're functionally identical then use them. Or don't. One's not right or wrong or more correct or what have you. The more important point is to be consistent in how you do it.
     
    glenneroo likes this.
  15. ericbegue

    ericbegue

    Joined:
    May 31, 2013
    Posts:
    1,353
    It must a matter of taste, but I find the version with var's more readable and I can infer the type at a glance with no problem. So, for me it's definitely var. Also, variable naming is another problem distinct from using var or not.
     
    TaleOf4Gamers and KyleOlsen like this.
  16. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    And just to address this - that's not the full story. It is syntactic sugar that is meant purely to save key strokes. Sometimes the side effect of those saved key strokes is better readability; sometimes it's worse readability; sometimes it just saves some key strokes.
     
  17. LaneFox

    LaneFox

    Joined:
    Jun 29, 2011
    Posts:
    7,462
    I agree it is a matter of taste in a lot of ways. I just disapprove when taste starts to bleed into creating bad habits that make it less friendly for other developers. Generally I run into this problem when var is abused, used as a lazy way to get around writing the actual type. Bad code and variable naming is separate, but I have yet to see a developer that writes exceptional code and also exploits var to the maximum extent possible while retaining readability. On the other hand, developers that use it sparingly are easier to collaborate with.

    It has uses, but has egg on it's face because so many lazy developers use it in all the wrong places and make it difficult for others to maintain their code.

    Even MSDN acknowledges this:
    Not that it is law, but its certainly worth consideration.
     
  18. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    For the class level this doesn't apply anyway, as this is not allowed in C#.

    And yes, you keep arguing with names that are simply bad, over and over again.
    Name the variables properly and you won't have much readability problems.

    Or in other words and from a different perspective, how would the explicit declaration improve readability for you, if you have a long method?
    Do you scroll up every single time you cannot remember what it was or would you consider to simply name it properly so that you already understand what it's supposed to be? Sure, IDEs help out with the hovering feature, but let's face it, it's still the name that is the root of the evil and forces you to look up the type again.

    Personally, i didn't like var in the beginning but once I started to use it, this immediately began to influence my naming conventions in such a way that I always name everything properly - provided I can as a non-native Englisch speaker.

    Nowadays, if I find that I rely on a variables explicit definition, I know that I've chosen a bad name. The better the name, the better others will understand the code and the explicit type will be less important. That's at least a positive effect it had on me.
     
    Last edited: Apr 27, 2017
  19. LaneFox

    LaneFox

    Joined:
    Jun 29, 2011
    Posts:
    7,462
    I'm glad to hear you've bettered your variable naming habits by using implicit variables to force that improvement.

    Unfortunately, not everyone does this and prolific var usage (read: when not required) is generally discouraged on large projects. When you work on a project where the code is outsourced you'll also find that the outsourced companies tend to not follow your coding standards (or any standards for that matter sometimes) which means segments of of your code base may not be following good naming conventions. Coupled with the lazy use of var, this is a serious issue. Of course, business, dont hire them, yada yada but really - unless you are the department director you have zero control over that other than complaining to your supervisor and if you're stuck with these people then you may have to deal with it for several years.

    So on all technical levels, var is great. Practically? It's often used as a crutch by lazy developers and this causes a lot of people to dislike seeing it.

    Working alone? It literally doesn't matter which way you want to do it since your choice doesn't affect anyone but you.
     
  20. ericbegue

    ericbegue

    Joined:
    May 31, 2013
    Posts:
    1,353
    @LaneFox
    Bad coding habits have nothing to do with using var or not. And explicitly specifying the type is not going to improve bad code.

    Essentially you are saying "I've seen bad coders using var, therefore every coders using var are bad coders.". That's a bit flawed, isn't it?
     
  21. LaneFox

    LaneFox

    Joined:
    Jun 29, 2011
    Posts:
    7,462
    Essentially you're saying "I have success with var, so using var is good". That's a bit flawed, isn't it?
     
  22. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,294
    If you find code written by other developers where the combination of var and variable name makes the code hard to read, you fix the code. Don't just go "ugh, this other developer wrote bad code", and let it go.

    If your company/group works in a way where people get angry if other people refactor the code they wrote, you're working in a toxic environment.


    @LaneFox, I was pretty ambivalent about this, but you've convinced me. Not a single one of your examples of code that's hard to read with 'var' would have been improved by including the type. It's all bad variable names.
     
    glenneroo, KyleOlsen and LaneFox like this.
  23. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,514
    How are we still discussing this?

    Here's the thing about rules... teams usually come up with rules for the team. The lead often being the one setting up those coding style guidelines.

    The guidelines are usually based around ease of reading as well as the reading skill level the lead expects of their team.

    Various people have different opinions about what is the best way of using various tools... all we're doing now is throwing our opinions at one another as if we're the right ones. Leave it to your lead to come up with that OR if you're the lead use your method.

    There's the obviously bad places to use it. But for the in betweens where half of us clearly understand the code, and the other half thinks it's a big no-no... well, you don't work on my team, so I dont' care!
     
    Kiwasi, Suddoha and LaneFox like this.
  24. LaneFox

    LaneFox

    Joined:
    Jun 29, 2011
    Posts:
    7,462
    Glad to hear it! ;)
     
  25. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,294
    citationneeded.jpg
     
    TaleOf4Gamers and monodokimes like this.
  26. LaneFox

    LaneFox

    Joined:
    Jun 29, 2011
    Posts:
    7,462
    [multiple project experience here], but ymmv - i felt that was pretty clear in my posts.

    Here's the MSDN comments on var usage. Although it seems like rather than discuss it people have become more concerned with destroying my posts. Either way, here's the links.

    https://msdn.microsoft.com/en-us/library/ff926074.aspx
    https://msdn.microsoft.com/en-us/library/bb384061.aspx

     
  27. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,992
    Yes, and my point is that this is a real thing, which Unity didn't invent. They just went with the way other game engines and scripting languages did things. Javascript didn't require variable declarations, older game engine Torque had it's own special script where you didn't need to know about types. (I don't know enough about how UnReal was scripted, except they had a Scratch-style GUI for some of it.) Shell scripts tend to be untyped. I got started in BASIC, who's name is about being a dumbed-down type-hiding language.

    I don't disagree that for some situations (will only write very simple, short programs, as a small part of your job and have no interest in learning more) a dumbed-down type-avoiding syntax is wrong.

    To me, the real problem is that many new Unity users are maybe in Jr. High, probably have access to a school Java class in school, and are primarily interesting in computer programming. For these kids, it's a real shame they get directed into dead-end shortcuts, by very well-intentioned users, like using var.
     
  28. mikael_juhala

    mikael_juhala

    Joined:
    Mar 9, 2015
    Posts:
    247
    It's impractical mainly because it wouldn't compile. You would get this:
    Error - CS0825 - The contextual keyword 'var' may only appear within a local variable declaration or in script code


    I don't see how those links support your claims, isn't it the opposite? For example: "Use implicit typing for local variables when the type of the variable is obvious from the right side of the assignment, or when the precise type is not important."
    Isn't this what others have been saying here?
     
  29. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    I'll bite (and especially because I thought my post would put this to bed but folks decided to spiral out and re-iterate the same thing over and over).

    No one is disputing this.

    No one is disputing this. We rubbed when it came to primitives but this seems cut and dry. If it's obvious by the right hand side then its fine.
    Code (csharp):
    1.  
    2. // how is this ok
    3. var thing = new Thing();
    4.  
    5. // but somehow this isn't
    6. var str = "";
    7.  
    Again, this just goes back to using bad variable names
    Code (csharp):
    1.  
    2. // these are both equally bad
    3. var temp = "";
    4. string temp = "";
    5.  
    Basically we all agree on this.

    90% of the examples in this thread are in this context

    Again (and again and again) if you don't like this pattern then don't use it.
     
    KyleOlsen and Suddoha like this.
  30. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    I think following given conventions is somewhat a different aspect.
    If you're told to follow instructions and conventions, well, you shouldn't ignore them in the first place. That's true, I totally agree here and I cannot and wouldn't say anything against it.

    But personally I can only repeat, the combination of both explicit typing and good naming is great but appears to be redundant (personal opinion, that's up to everyone) and often superfluous once you loose sight of the declaration, it won't help you any longer and yet the code should still make perfect sense in order to understand the logic (without having to think about the type again, therefore not caring about whether it's been declared using 'var' or 'int', for example).

    It can literally help to write code that's contextual understandable and more descriptive throughout the whole method's scope.
    One could even argue the other way around, if code doesn't make sense without explicit types at declaration time, how would you focus on the actual logic?
     
    Last edited: Apr 27, 2017
    KyleOlsen likes this.
  31. astracat111

    astracat111

    Joined:
    Sep 21, 2016
    Posts:
    725
    So far, after about 6 months of learning C# every day, I can't stand the var keyword. It's insanely important that code is readable from my viewpoint. All the time I'm running over my old code and renaming it to be more literal sounding. "SetSound" becomes "PlaySound" for example or whatever.

    It's extremely important to me to declare values by their type, as when I read my code later I want to know exactly what's happening from reading it without having to have any commenting.

    On the other hand, when Unity gets the use of the dynamic keyword I'll be using that one.
     
  32. ericbegue

    ericbegue

    Joined:
    May 31, 2013
    Posts:
    1,353
    That's not what I am saying. Using var so far has been good for me, and so far no one in my teams has complained about it. Neither am I saying every coders using var are good coders.

    Any programming technique/feature can be abused to produce bad code. But you can not take the usage of a single feature and name it a discriminant between good and bad coders.

    var is a good addition to C#: it decreases repeating the type on both side when declaring variable (decreases keystroke and increase readability) while the variable is still strongly typed. Now, if there are situations when using var makes the type ambiguous, then don't use var if knowing the type is critical. Simple as that.
     
    KyleOlsen likes this.
  33. monodokimes

    monodokimes

    Joined:
    Feb 2, 2016
    Posts:
    24
    I'd be interested to hear your thoughts another 6 months down the line, or a year. When I first started writing C# for work I was scared of LINQ and would go to any lengths necessary to avoid it, but have since learned to love it and now I find it indispensible; often to the horror of the uninitiated. I imagine a similar experience could occur with 'var' and typing.
     
  34. astracat111

    astracat111

    Joined:
    Sep 21, 2016
    Posts:
    725
    I don't know, I just feel like when I read my code I should have that type name there every time, I guess that could change if I was working with someone else, though.
     
  35. monodokimes

    monodokimes

    Joined:
    Feb 2, 2016
    Posts:
    24
    As others have said, teams make rules for teams; there aren't any hard and fast rules on coding convention. You do you! Flexibility is key, not only for teamworking in general but especially so in a field like programming. Over time I've learned to rely less on types and more on names to express intent, and so I've naturally tended towards using 'var' because types just aren't important enough to write in full every single time. I wonder how many keystrokes I've saved myself by now? (I imagine I've made them all back by posting in this thread...)

    Honestly, I didn't realise 'var' was such a stickler for some people; definitely one or two flustered posters in here! :p
     
    astracat111, KelsoMRK and ericbegue like this.
  36. astracat111

    astracat111

    Joined:
    Sep 21, 2016
    Posts:
    725
    @monodokimes

    I think it comes down to that. On a team, you need to have that flexibility, while when you're alone it's a very different story, you can be pretty rigid with yourself if you want to be.
     
    monodokimes likes this.
  37. WarrenMarshall

    WarrenMarshall

    Joined:
    Jun 7, 2015
    Posts:
    44
    Since I saw this thread, I started using "var" in my code. It's brilliant, thank you!
     
  38. monodokimes

    monodokimes

    Joined:
    Feb 2, 2016
    Posts:
    24
    @astracat111

    Aye I'll agree to that for sure, I learned pretty early on that if I didn't instill good conventions as a habit then I'd eventually go insane. As such I'm pretty brutal on myself about proper names, formatting and keeping comments and experimental code to an absolute minimum.