Search Unity

Who ritualistically uses the C# "var" keyword?

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

  1. ArachnidAnimal

    ArachnidAnimal

    Joined:
    Mar 3, 2015
    Posts:
    1,802
    I've been using C# for over a year ago.
    Honestly, I still don't make use of the "var" keyword.
    I always explicitly state the type.

    I read the C# language specification, and it's worded in a way that suggests that if you don't use the keyword, then you are programming incorrectly.

    Does anyone else tend to not use the var keyword?
    I just cannot get into a habit of using it. It never even crosses my mind to use it.

    This is what the MSDN site says:

    Implicitly Typed Local Variables
     
    Last edited: Apr 23, 2017
  2. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    It's useful in a couple of cases.
    • To avoid nonsense such as Dictionary<string, List<int>>.
    • To reduce direct dependency on types defined in third party libraries.
    But I wouldn't call not using it bad practice. Ultimately it's just syntactic sugar. Under the hood typing a variable explicitly and using car are identical.
     
  3. mikael_juhala

    mikael_juhala

    Joined:
    Mar 9, 2015
    Posts:
    247
    I generally don't use it, but sometimes it does help with readability. In the case below there's also no problem knowing what the "var" is.

    Code (CSharp):
    1. // instead of this...
    2. Dictionary<SomeLongNamedType, AnotherLongType<GenericType>> someDescriptiveName = new Dictionary<SomeLongNamedType, AnotherLongType<GenericType>>();
    3.  
    4. // we can have this:
    5. var someDescriptiveName = new Dictionary<SomeLongNamedType, AnotherLongType<GenericType>>();
     
  4. SGM3

    SGM3

    Joined:
    Jun 10, 2013
    Posts:
    81
    If I am not mistaken, var was introduced for anonymous types. It has been grossly overused. Personally, I prefer implicit types and var when needed. However, when using code snippets for say foreach, which by default uses var, I leave it.

    Var is just a compiler trick, and will generate the appropriate type when compiled. If you are not using an IDE that can catch improper casts then var can become an enemy.
     
    mxch_ likes this.
  5. LMan

    LMan

    Joined:
    Jun 1, 2013
    Posts:
    493
    Using var everywhere really hurts readability- so I don't use it that often.

    When I'm trying a lot of different things, var can mean a lot less typing. For instance, sticking var in a foreach loop means I can change the type of the collection without breaking anything. While it may not be necessary in the end, it's a nice practical tool.

    var comes in very handy when using LINQ and Lambda functions of course, as I'm sure others will mention.
     
    astracat111, Ryiah and Kiwasi like this.
  6. LaneFox

    LaneFox

    Joined:
    Jun 29, 2011
    Posts:
    7,498
    If you're using var, you should be using JS because only jerks type that crap and expect people to actually be able to maintain and read code better than explicitly type variable definitions.

    tl;dr use var's if you're a jerk.
     
  7. ericbegue

    ericbegue

    Joined:
    May 31, 2013
    Posts:
    1,353
    No, I do use var all. the. time. It saves me a lot of keystrokes and it makes the code far more readable, particularly for those long type names or nested generics as @mikael_juhala example. You already have the type explicitly defined on the right side, why would you need it on the left side again? So yes, it definitely increases readability by decreasing repetitions.

    How does it hurt readability?

    @LaneFox

    I'm using var all the time and I'm not a jerk, jerk. Don't confuse C# var with JS var. C# var is strongly-typed. The type is inferred by the compiler, but it is strongly-type nonetheless. Whereas JS var allows to change type at runtime, C# var does not. You get a compilation error if you try:
    Code (CSharp):
    1. var str = "hello!";
    2. str = 1.0f; // Compiler says "Nope."
    However, if you really want to change the type at runtime you have to use the dynamic keyword, though this is not supported by the Mono version used by Unity.
     
    Last edited: Apr 23, 2017
    DaneGillburry and KyleOlsen like this.
  8. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    You don't need to be disrespectful just because you don't like to use it.
     
    ericbegue, Deleted User and Ryiah like this.
  9. LMan

    LMan

    Joined:
    Jun 1, 2013
    Posts:
    493
    Could vary between IDE's, but I find it easier to tell some things apart with the type on the left side. Some constructors may look similar at a glance, so its nice to not have to hover over to find out what it is.
     
    Ryiah likes this.
  10. passerbycmc

    passerbycmc

    Joined:
    Feb 12, 2015
    Posts:
    1,741
    I mix and match, if it is obvious from the constructor I will use var and if if the type name will be crazy long due to generics I will use var. Also useful for LINQ since that always returns something like IEnumerable<T> and can get long if your T also has a generic.

    To be fair if you are unsure of the type and need the ide to tell you that is generally on a usage of the type not where it is declared.
     
  11. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,996
    If you care about the official specification, the general consensus is to use var as little as possible. Just search "C# var," paying extra attention to the StackOverflow discussion. They cite the MS C# sites use of the word "rarely."

    But as far as Unity, remember that Unityscript was the starting language, and one of the advantages was you didn't need to know about types, at first. Being able to use (roughly) var n=3; var name="Jorlin"; was considered an advantage for new users. And then there's sometimes an instinct to use every language feature where ever it can be used. Especially if you've just learned it.

    My thinking is that whether or not to use var is a distraction. It sucks concentration away from things that will actually matter. Deciding never to use it, and never to even think about using it will probably result in better programs.
     
    JoeStrout and Ryiah like this.
  12. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    21,128
  13. ericbegue

    ericbegue

    Joined:
    May 31, 2013
    Posts:
    1,353
    What do you mean? A constructor literally defines the type.
    Code (CSharp):
    1. var obj = new GameObject();
    It's more than obvious that obj is of type GameObject. Repeating the type on the left is redundant.
     
    Munchy2007 and KyleOlsen like this.
  14. Tzan

    Tzan

    Joined:
    Apr 5, 2009
    Posts:
    736
    It never occurred to me to use var.
    I don't have any LINQs ... that I know of. :D
     
  15. Deleted User

    Deleted User

    Guest

    Looks handy; does it work in Unity?
     
  16. passerbycmc

    passerbycmc

    Joined:
    Feb 12, 2015
    Posts:
    1,741
    Yes
     
    ericbegue likes this.
  17. LMan

    LMan

    Joined:
    Jun 1, 2013
    Posts:
    493
    You're right of course, I was wrong about constructors.
     
    KyleOlsen likes this.
  18. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,527
    As a ritual? nope... no I don't.

    Do I use it? Yes, yes I do.

    It's a very useful tool, especially when constructing objects of very long type names.

    Code (csharp):
    1.  
    2. PlayerRangedWeaponAnimationController controller = new PlayerRangedWeaponAnimationController();
    3. //or as a component
    4. PlayerRangedWeaponAnimationController controller = this.AddComponent<PlayerRangedWeaponAnimationController>();
    5.  
    6. //vs
    7.  
    8. var controller = new PlayerRangedWeaponAnimationController();
    9. //or as a component
    10. var controller = this.AddComponent<PlayerRangedWeaponAnimationController>();
    11.  
    Yeah... I kinda prefer the ladder.

    There is also the anonymous typing, like with linq, where it's extremely useful (primarily since the type name is unkown otherwise).

    Of course, if 'var' hurts the readability... I'll probably avoid it. This could happen if say a function returns an object, and the method name isn't exactly descriptive as to what the type is.

    Code (csharp):
    1.  
    2. var obj = otherObj.GetChild(0);
    3.  
    A very distinct one would be:

    Code (csharp):
    1.  
    2. for (var t in transform)
    3.  
    ... sort of forces you to know the api... not as readable (also, since transform defaults to IEnumerator, as opposed to IEnumerator<Transform>, t is now typed object rather than Transform like you want).

    As for this though...

    I agree that MSDN sometimes is very authoratative with its standards and naming things... it says similar things about the '_' and also parts of the documentation suggesting you should never say "fire event" but rather "raise event", despite other parts of the documentation using the phrase "fire" anyways.

    This sort of thing does annoy me, and is often the fault of the documentor writing that specific bit of documentation, or the culture of the product changing over time.

    But... as the phrasing of the use of 'var' goes in the quote above... I don't take it as saying you're programming incorrectly. But rather as stating the situation you would use it.

    Which is the places most people DO use it. Because it's useful.

    Use it when the variable is obvious (like with new) or when type is not important (like with anonymous types).

    I think you might be reading too far into it if you're taking anything more from it then that.

    That's what a hammer is for!
     
    Last edited: Apr 24, 2017
  19. Deleted User

    Deleted User

    Guest

    I'm getting an "error CS0103: the name "var" does not exist in the current context" message when I write this:
    Code (CSharp):
    1. var obj = new GameObject ();
    which is an example given in a previous post here.
     
  20. UziMonkey

    UziMonkey

    Joined:
    Nov 7, 2012
    Posts:
    206
    The var keyword should be used whenever it the type of the object is obvious. It's more concise and it makes it easier to refactor your code. This is a change being seen in many languages, and is universally liked. For example in C++11 there is a new auto keyword that does the same thing as var.

    Think of it this way, if you're saying Vector3 pos = transform.position;, why are you even saying Vector3? You know the position is a Vector3. All positions are a Vector3. Instead, say var pos = transform.position;. It's both less typing, still perfectly clear (assuming the reader has even the most cursory understanding of Unity) and easier to refactor. If the type of the right hand side changes, you don't have to change the type on the left-hand side.

    I think the most important (and also smallest) change is that of noise. Having all these types for variables adds a lot of noise to the code, it makes it harder to read, it makes it longer than it has to be, it makes it more horizontal than it needs to be. It's a good change, and it's a good practice to get into.

    There are times when you shouldn't use it though. Like var num = someUnknownFunction(); is a bad thing. Presumably you don't know what someUnknownFunction returns, you should be manually defining the variable type here to annotate a function that's not used very often. Here that extra information is welcome, it's a notice to other coders or your future self that this is a float or something. Yes, you could do the same with a comment, but comments add unnecessary noise to the code that should not be there unless there's a real reason. I know "self-documenting code" is often used as an excuse not to write comments or documentation, but it's a real thing. If you write your code simple and clean enough that it's easily apparent what's going on, you generally don't need to write excessive comments or detailed documentation. Annotating your code with types when the type is not clear is very useful here.
     
    ericbegue likes this.
  21. UziMonkey

    UziMonkey

    Joined:
    Nov 7, 2012
    Posts:
    206
    That should work. I have similar code in literally hundreds of places in my code (thought you probably shouldn't be using new GameObject). Is there an error on the previous line of code? Are you missing a semicolon?
     
  22. Deleted User

    Deleted User

    Guest

    Well, maybe I'm doing it wrong; the compiler says:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class UseOfVar : MonoBehaviour
    6. {
    7.     var str = "Hello!";
    8.  
    9.     void Start ()
    10.     {
    11.         print (str);
    12.     }
    13. }
    Ah, now it works! No error this time:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class UseOfVar : MonoBehaviour
    6. {
    7.     void Start ()
    8.     {
    9.         var str = "Hello!";
    10.         print (str);
    11.     }
    12. }
     
  23. WarmedxMints

    WarmedxMints

    Joined:
    Feb 6, 2017
    Posts:
    1,035
    Yes, you are using it incorrectly in the first script. As the compiler error states, you can only use var for a local variable declaration. This means within a function. A global variable must be declared as a specific type.
     
  24. Deleted User

    Deleted User

    Guest

    I had understood.
     
  25. Pengocat

    Pengocat

    Joined:
    Dec 7, 2016
    Posts:
    140
    I agree with those that var is good to use when the thing on the right reveal the type at a glance.

    It is like if you are at the ticket office to an amusement park you don't ask for a ticket to "Fun world" when there is a big sign above you with the name of the park "Fun world". You just ask for A ticket. If the sign above you suddenly changes because you now arrived at "Waterworld" you still just ask for A ticket.

    I know that is a very verbose explanation of something rather simple but that's my argument for why "var" actually makes sense to use in certain cases.
     
    StarManta likes this.
  26. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    I mean....not a great example since int and var are the same number of characters. Long class names and nested generic collections (like the examples others have posted) are where you get the most bang for your buck usually (along with anonymous types generated by LINQ expressions).

    Just for fun I'll also mention enumerating KeyCollections in a dictionary which is just obnoxious because it's an inner type of Dictionary<TKey, TValue>. So you can end up with dumb stuff like this
    Code (csharp):
    1.  
    2. Dictionary<string, List<int>> stringToInt = new Dictionary<string, List<int>>();
    3.  
    4. foreach (Dictionary<string, List<int>>.KeyCollection key in stringToInt.Keys)
    5. {
    6.  
    7. }
    8.  
    which can just become
    Code (csharp):
    1.  
    2. var stringToInt = new Dictionary<string, List<int>>();
    3.  
    4. foreach (var key in stringToInt.Keys)
    5. {
    6.  
    7. }
    8.  
    Or if you just want to enumerate the dictionary directly
    Code (csharp):
    1.  
    2. foreach (KeyValuePair<string, List<int>> kvp in stringToInt) { }
    3.  
    4. foreach (var kvp in stringToInt) { }
    5.  
     
  27. SGM3

    SGM3

    Joined:
    Jun 10, 2013
    Posts:
    81



    Using var:
    Code (CSharp):
    1. public class VariablesAndFunctions : MonoBehaviour
    2. {
    3.     int myInt = 5;
    4.     int myNewInt;
    5.  
    6.     void Start ()
    7.     {
    8.         myInt = 9;
    9.         myNewInt = MultiplyByThree (myInt);
    10.         print (myNewInt);
    11.     }
    12.  
    13.     int MultiplyByThree (int number)
    14.     {
    15.         return number * 3;
    16.     }
    17. }
    Even Shorter =D
     
  28. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    Yeah, @KelsoMRK 's examples are where I get the most mileage out of var. In addition to just being easier to type and easier to read, it's also easier to refactor. If in that last example I want to start using floats instead of ints, I have to change that in one or two places, as opposed to every time I use the dictionary in a loop.
     
    Kiwasi and KelsoMRK like this.
  29. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    This also becomes more powerful with the advent of C# 7 where methods can return Tuples
    Code (csharp):
    1.  
    2. (int, int, int) GetTheNumbers()
    3. {
    4.     return (1, 2, 3);
    5. }
    6.  
    7. var theNumbers = GetTheNumbers();
    8.  
    Now granted, you do lose some clarity if your method names are garbage (like mine are in this example). But there are a lot of different ways to declare using var when it comes to Tuples. https://blogs.msdn.microsoft.com/dotnet/2016/08/24/whats-new-in-csharp-7-0/
     
    LaneFox and LMan like this.
  30. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    I use it where it is useful, but overuse can make it hard to read code. So practically about 99% of the time I don't use var.
     
  31. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,187
    I was surprised how this discussion grew. Honestly, use what works for you. If you're on a team/working for a company, chances are you have some standards that are set in place for the group. If you don't have standards, maybe work on developing some. If you're developing solo, use what works for you.

    I use var for different things, but I don't go out of my way to use it, nor do I avoid it. It's just another part of coding.
     
  32. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    I don't feel anyone has yet adequately addressed the ritualistic uses of var.

    I mean, suppose you put some real effort into it — using var at midnight under a full moon, inside a carefully-painted pentagram on some sacred ground deep in virgin woods — surely you could get some effect besides type inference?
     
  33. SGM3

    SGM3

    Joined:
    Jun 10, 2013
    Posts:
    81
    This is true. Purhaps a visual studio plugin that plays a clip from some seance music every time 'var' is typed?
     
  34. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    We carefully avoided the use of var in my last game jam project. Which was about ritualisticly summoning demons. We did it precisely to avoid this kind of side effect.
     
    JoeStrout likes this.
  35. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    I never use var because I can barely understand my own code, so I don't think I'll make my job harder... need everything to be clear.
     
  36. labarilem

    labarilem

    Joined:
    Mar 4, 2017
    Posts:
    4
    While typing "var" can be faster than typing "Dictionary<Type1, List<Type2>>", you will lose readability and time to look up the type too. That's basically why I don't use the var keyword.
     
  37. makeshiftwings

    makeshiftwings

    Joined:
    May 28, 2011
    Posts:
    3,350
    I use it all the time because Resharper tells me to, and at this point in my life I've just accepted that Resharper is smarter than I am. :oops:
     
  38. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,527
    Best post in this thread!
     
    ChewyMicha and makeshiftwings like this.
  39. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    But....but.....the type is in the constructor right next to it......

    Here's another one! Just because I had to do it a few minutes ago....

    When you're in a namespace that has a class defined whose name collides with a class in another namespace that you want to use. IE - I have a class called Button in FracturedState.UI; I want to use a UnityEngine.UI.Button in another class in FracturedState.UI; the compiler will always take the shortest route and assume my Button.
    Code (csharp):
    1.  
    2. UnityEngine.UI.Button btn = AddComponent<UnityEngine.UI.Button>();
    3.  
    4. var btn = AddComponent<UnityEngine.UI.Button>();
    5.  
    Of course I could do this
    Code (csharp):
    1.  
    2. using UnityEngine.UI.Button = Btn;
    3.  
    but (because I'm a cool guy and I wrote our UI framework years before Unity rolled their's out) I've got several of these collisions.....
     
  40. mikael_juhala

    mikael_juhala

    Joined:
    Mar 9, 2015
    Posts:
    247
    Depends on the use-case:

    Code (CSharp):
    1. // I think here the type might be needed (of course depends on the method's name and class)
    2. Dictionary<Type1, List<Type2>> dict = someMethod();
    3.  
    4. // Here having the type twice is redundant
    5. Dictionary<Type1, List<Type2>> dict = new Dictionary<Type1, List<Type2>>();
    6.  
    7. // And now it is getting longer
    8. Dictionary<Type1, List<Type2>> dict = new Dictionary<Type1, List<Type2>>(capacity, new SomeEqualityComparer());
    9.  
    10. // Which could be simplified with a simple 'var'. The type is still completely clear.
    11. var dict = new Dictionary<Type1, List<Type2>>(capacity, new SomeEqualityComparer());
    (edit: Of course, if you were only referring to the first use-case, then I'm just agreeing with you here.)
     
  41. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Honestly, the first use case is the only one I use var for. With auto complete typing out a long name costs me only a couple of keystrokes. Looking up the return type of a third party method in some poorly documented API can cost a fair bit of time.

    And of course var can only be used for local variables, which means you are going to abandon the reference pretty soon anyway.

    It's especially useful for iteratable types or working with server libraries.

    Code (CSharp):
    1. var results = GetResultsFromServer()(
    2.  
    3. foreach (var result in results){
    4.     Debug.Log(result.ToString());
    5. }
     
  42. monodokimes

    monodokimes

    Joined:
    Feb 2, 2016
    Posts:
    24
    'var' is a godsend, I use it almost exclusively when working with local variables.

    The only times I don't use 'var' are when I'm declaring variables for assignment later, for example with TryParse() methods that require an out parameter. A similar pattern would be used for working with Raycasts and RaycastHits.

    Code (CSharp):
    1. int result;
    2. Int32.TryParse("3", out result);
    Because of this, if I see 'var' I can think 'oh, it's a normal local variable used in a normal way.' If I see an explicit type in the variable declaration then that means something about this particular variable is different to usual, for example the 'out' variable example above.

    Generally the type of the object should be clear from usage. You'll get references to an object from a constructor, a method parameter or a class field, all of which explicitly declare the type, so there's no reason to use more keystrokes than you have to.

    I can't speak for MonoDevelop, but Visual Studio has lots of features to ease usage of 'var'; hover your mouse over a 'var' usage and it'll show you the type. Press F12 to be taken to the definition of any given code element. Probably some others buried in my subconscious that I can't recall at the moment.

    Types in C# are just another code element; they're important to understand, but once you understand them you don't want to see them everywhere. Like LINQ, 'var' allows for more streamlined code, expressing the intent more succinctly and deferring the question of whether it's a legal line of code to the compiler, which is smart enough to know, and almost certainly knows better than you do anyway.

    Trust your tools, kids; let them do the hard work!
     
    Deleted User and Kiwasi like this.
  43. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,332
    It's also important to write code that reads relatively well without knowing exactly what the type is.

    Say you have something like:

    Code (csharp):
    1. var page = ToHTML(blogPost);
    2. page = AppendHeader(page, currentLayout.GetHeader());
    3. page = AppendFooter(page, currentLayout.GetFooter());
    4.  
    5. renderer.Render(page);
    You don't know what type page is. It might be a string, it might be some type that wraps some HTML, it might even be a byte-array! That doesn't really matter, though. You understand what's going on from the names of everything, and the type information would only be noise:

    Code (csharp):
    1. WebPageContents page = ToHTML(blogPost);
    2. page = AppendHeader(page, currentLayout.GetHeader());
    3. page = AppendFooter(page, currentLayout.GetFooter());
    4.  
    5. renderer.Render(page);
    It's not a big difference, but I spend a lot of time reading code. The less information that I need to take into consideration to understand the intent of the code, the faster I can get stuff done.

    Try Rider, it's even smarter! No more "You're not calling the method named "start" from anywhere, so you can safely delete it".
     
    Ryiah and monodokimes like this.
  44. LaneFox

    LaneFox

    Joined:
    Jun 29, 2011
    Posts:
    7,498
    Dang, that is actually useful. I mean, I like to troll a bit with threads like this by raging out on var usage but thats actually something I would probably use vars for. I also had no idea mutli-returns were a thing.

    Up until now I generally don't use var for anything but dictionaries and kvp's on inner scope so this is kinda nice. It's going to be a pretty long time until we see C#7 in Unity, though.

    The main thing I use var's for is when I'm too lazy to type something (or too lazy to look it up) and I know resharper will fix the definition for me after I type it.
     
    Last edited: Apr 25, 2017
  45. LaneFox

    LaneFox

    Joined:
    Jun 29, 2011
    Posts:
    7,498
    Well, you could just tell ReSharper to prefer Explicit definitions instead of var :p (theres like, all the options in the resharper config.
     
  46. Deleted User

    Deleted User

    Guest

    Or you could just read the right side assignment.
     
  47. Deleted User

    Deleted User

    Guest

  48. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,996
    There it is - AnnSchmidt has provided the conclusive connection between use of var and dark rituals. In Player.cs we see that var is preferred by the same vile turnstile-jumping, non-flossing monsters who don't cache their Components. They don't even use K&R style curly-braces.
     
    LaneFox likes this.
  49. LaneFox

    LaneFox

    Joined:
    Jun 29, 2011
    Posts:
    7,498
    The IDE is of unnatural origins too, the method isn't even collapsible.

    Savages.
     
  50. Deleted User

    Deleted User

    Guest

    The ide seems to be monodevelop; collapsible or not collapsible, you can choose in the options. :)