Is using 'var' instead of specific types really ok?

I recently saw a video online that touted the wonders of the Rider IDE, so I downloaded the trial and have been working with it’s features, having previously been using Visual Studio.

I’m very new to C#, having a heavy background in C ages ago, and a bit of C++ sprinkled in here and there, mostly through things like Arduino coding.

Every bit of coding I’ve ever learned is to type things properly. Not wasting memory by using the right types, not causing possible compiler or runtime issues by playing fast and loose with types that will work, but might not be ideal.

After installing Rider, I have tons of declarations that are being flagged and I’m being told to simplify it by just using var (something Visual Studio never complained about). Delcare an ItemData (internal class) as var. Declare a vector2 or 3 as var. I’m seeing all those and it’s making my oldschool coder brain short circuit.

Really? Var is ok? Is it better than strictly typing these variables? Is it not better or worse, and Rider is just trying to standardize my code? Is it actually better?

Someone reassure me that I’m not being horrifically sloppy by using var? It feels so… dirty… shudder :slight_smile:

Seriously though… is there any performance difference?

Your variables will still be statically typed when using var. There is absolutely no change to the compiled code and static analysis works exactly the same. The only difference is the way it looks on the editor.

It’s up to you what you prefer, but I like var because it’s shorter to type and easier to change the type during refactoring.

2 Likes

It’s entirely personal preference and makes no difference when your code is compiled and executed.

I much prefer explicit type declarations, and I’m sure there’s probably a setting in Rider to disable that warning, but I wouldn’t know, since I’ve never used Rider.

3 Likes

There’s no performance difference. Whenever you use var, the type will be inferred based on what’s assigned. So you’ll still deal with strongly typed variables.

Opinions about the usage vary a lot.
Many people like to be explicit with type names and don’t use it at all.
Others use it when it’s more than obvious what’s being assigned or when type names are too long (think about generics, or even nested generics).
Some use it nearly everywhere - I’m one of those, for various reasons.

Anyway, when you work in a team, for someone else or for a company, you’re likely going to use their conventions.

Personally, I would disable that inspection in Rider.

var is really convenient, and I use it a lot. But sometimes it’s important to spell out the type of a variable for code clarity and readability. If Rider flags that as a warning, I think that’s a mistake.

Thanks all. Really feels weird not explicitly typing a variable. I’m probably going to disable that feature in rider. Half my screen has green squiggles under variable assignments.

1 Like

If Rider is anything like IntelliJ (another JetBrains IDE for Java), it should be really easy to disable just that specific inspection and leave everything else alone. Happy coding!

It’s called type inference. It’s not dynamic typing at all, the compiler simply infers the type at compilation time based on assignment. The C++ equivalent is the “auto” keyword. It’s good to reduce type repetition in local variable initialization and iteration, but as everything, it can be misused and make code harder to read in some cases.

All this new C# stuff is hard to adjust to. I spent a long time googling how the hell to free memory in C#. Then a long time to calm the twitching and existential dread I was experiencing by not freeing allocated memory, relying on some “garbage collector” to do it for me.

I’m apparently older than I thought I was. :stuck_out_tongue:

“Back in my day, we had to free the memory used in a linked list when we were done with it! Oh the stories I could tell you whippersnappers!”

Gotta go, my hip is acting up. Guess it’s gonna rain.

2 Likes

I hate var, just because it turns reading someone else’s code (or even my own old code) into a hassle. The worst is when people post a bit of their own code here on the forum, and every variable is declared as var without any context about what it is, and they wonder why they aren’t gett much help.

“var” is only legal code if the type can be immediately determined in the line in which it’s declared, so I’m not sure how this would be an issue in most cases? Like “var x = GetComponent();” makes it quite obvious what type x is. I guess if they have a method (which they wrote) that they use for the initial assignment it wouldn’t be completely clear from that snippet (and I would agree that var is a poor code style choice for that kind of assignment), but I hardly ever come across a situation like that in the forums.

2 Likes

Yeah I’m talking about code like:

var terribleVariableName = TerribleMethodName(variableNotEvenSeenInTheCodeSoFar);

Not often, but I’ve seen it a few times here, and it is usually someone screaming that they need help quickly.

I sometimes use var on the forums because the person who started the thread didn’t give enough context to deduce what the type of a certain variable would be (is it a Transform? A GameObject? Something else?), but I know that I can pretty much always do something like this:

var x = Instantiate(<someone's prefab reference of unknown type>);
Transform t = x.transform;

It’s a forum hack :smile:

This was already touched on, but just to be a little more explicit: “var” uses an inferred type, which is different from a variant type you may have seen in languages like JavaScript, PHP, or Visual Basic.

A variant-typed variable can change its type over the course of the program depending on what value is assigned to it, and uses extra memory to keep track of what its current type is. For instance, you could assign an integer value to the variable, and then somewhere later on you could assign a string value to the same variable.

An inferred type has the compiler guess what type you meant based on the context of the declaration, but that guess is set in stone and can’t change; as long as the compiler guesses correctly, it compiles to the same result as if you had declared the type explicitly.

Well, that depends on what you mean by “immediately”. It’s legal to do this:

double x = 7.9;
var y = x;

You can easily infer the type of y if you already know the type of x. But x might have been declared 20 lines earlier, or even in another file entirely. The type of y does not have to appear anywhere in the line of source code where it is declared.

I’ve used “var” a lot in sample code I’ve posted to the forum, but usually only when I’m responding to a question where the types of the variables were unclear in the original, so I don’t know what the actual type is. Which is surprisingly common, and sometimes even reasonable–e.g. there’s lots of questions about List manipulation where it really doesn’t matter what “T” is, so I end up writing example code with lines like var currentElement = myList[index];, which I wouldn’t normally write in my own actual programs but makes the example more generic.

The official purpose of “var” is to be a shorthand for cases where the type is both complicated AND either (a) obvious or (b) not helpful to spell out. The typical examples are things like

// Type is already written explicitly on the same line, and would be tiresome to type or read twice
var someCollection = new Dictionary<string, List<Queue<MapTile>>>();

// Type is some weird collection of properties composed on the fly that doesn't have a meaningful name
var someEnumeration = 
    from WhizBang x in allMyWhizBangs
    where x.foo == 7 && x.bar == 9
    select new {x.name, x.serialNumber, x.color, x.flavor};

I think “var” is fine in extreme cases, but as a rule of thumb I avoid it.

It seems obvious that C# IDE’s simply prefer the newest features. It’s not recommending var for any more complex reason than that. And style doesn’t have any deep learning curve – for the most part, a suggestion either immediately looks better, or it doesn’t. As you point out, using the real type reminds you of the type, and knowing types is important. Even in Vector3 d=new Vector3(x,y,z);, the first Vector3 makes it 3% more readable. What’s the practical reason for var everywhere? I’ve never seen someone telling us to use var and explaining why. I can explain why open-curly goes on the same line (if I couldn’t, I wouldn’t do it that way). Sure, some style is “any way is fine, but we need to be consistent”, like variable naming. But var clearly isn’t one.

Another thing to consider is that C# didn’t want var at first. Other languages had it, but C# passed. Maybe they didn’t like it, or more likely, they didn’t think it was important enough to add yet. Var had to be added for LINQ, since some on-the-fly database types can’t be written out. So now we should use it everywhere?

Or think of it from the IDE makers point-of-view. Being current is important. Having more possible suggestions is better. It follows that we need more suggections of current features, enabled by default so you can’t miss how up-to-date it is.

Have to agree. It seems like there’s a market-shift towards making programming more implicit, and I just don’t see the benefit in that other than faster typing.

It looks really cool in tech talks. :smile:

1 Like

Got me there.

I started using var when it was first released and haven’t looked back ‍/shrug

2 Likes

When I first started using C#, I was very much in the “always use explicit types” camp. Over time however, and perhaps due in part to my professional work requiring the use of javascript, I’ve grown used to defaulting to ‘var’. I will attempt to outline my own reasons for using var, and respond to some of the critiques above. This isn’t an attempt to convince anyone else to use ‘var’, just an explanation of the philosophy behind why I am okay using it. Hopefully I can shed some light for @Owen-Reynolds in giving some ‘why’ behind the ‘what’ :slight_smile:

Any decision on what syntax to use where is (or should be, in my humble opinion) based on three factors: ease of writing code, ease of reading code, and ease of modifying existing code. I’m setting aside for the moment the added constraints that operating within a larger company create, where any number of programmers may need to interact with the same piece of code over a long period of time.

I see others in this thread downplaying the importance of being able to write code quickly. As I have been programming for longer and longer, the way I look at code has changed. I don’t pay much conscious attention to what specific code I am writing – instead, I am largely focused on achieving the end goal I have in mind. The more the language fights me on syntax, the more I am writing code instead of making programs. ‘var’ simply enables me to do more of the latter.

However, programmers spend far more time reading code than writing it, and readability seems to be most people’s main gripe with using ‘var’. It’s not an unfair criticism, as ‘var’ does not provide any semantic meaning on its own. There is an important point hidden inside @Joe-Censored 's succinct critique of a poorly used ‘var’, though:

var terribleVariableName = TerribleMethodName(variableNotEvenSeenInTheCodeSoFar);

In this snippet, the ‘var’ is actually the least offender. Far worse are the terrible names. A type declaration happens only once, for any given variable. The variable name itself is used everywhere else. If I named all of my variables single characters, a, b, c, etc., my code would be a nightmare to read whether I were to use explicit type declarations or not. I am a firm believer in self-documenting code, and the guideline that comments should endeavor to only explain ‘why’, not ‘what’. A large component of this is in effective variable names. In a mirror to my comments on writing code, the more necessarily verbose the language is, the more I am reading code instead of understanding intent. I find that good variable names go way further to that end than does explicit typing. You may respond, “why not do both, then”? Fair point, but I would argue that being redundant doesn’t necessarily help readability. If a variable looks like a Duck and Quacks() like a Duck, then you really don’t need to specifically label it as being a Duck. I find that a lot of my variables are assigning very obvious things with very obvious variable names, like declaring a Transform transform or Rigidbody rigidbody. I find this tedious.

‘var’ also has a hidden attribute that contributes towards readability that I haven’t seen touched on before; it is always 4 characters long, including the space separator. It puts variable names at a consistent depth on the screen and allows for easy visual scanning.

The utility for modifying existing code should be obvious – if you chance the implicit type of the underlying variable, you don’t have to change the declared type.

I don’t use ‘var’ universally though, since my loyalty is to maximizing the three factors first and foremost, and there are definitely places where ‘var’ is not as useful, or impossible to use. Separating declaration from assignment doesn’t allow for implicit typing at all, so that’s obviously out. I have gotten caught several times by the float/int convention, where I have assigned a 0 to a variable I want to be a float. For this reason I have become more explicit when declaring float/int types. This is made easier by the fact that ‘float’ and ‘int’ are both of similar length to ‘var’, and at least in my version of Visual Studio, highlighted in the same color.

But what do I know, I’m one of the weirdos who spaces all my parentheses out and puts brackets on same line :smile:

if( hv.x != 0 && hv.y != 0 ) {
    movementQueued = true;
    queuedMovement = hv;
    queuedMovement.x = 0;
    hv.y = 0;
}
if( animGraph.blockingMovement ) {
    movementQueued = true;
    queuedMovement = hv;
} else {
    PerformMovement( hv );
}
3 Likes