By ljs


2008-09-03 11:29:57 8 Comments

After discussion with colleagues regarding the use of the 'var' keyword in C# 3 I wondered what people's opinions were on the appropriate uses of type inference via var?

For example I rather lazily used var in questionable circumstances, e.g.:-

foreach(var item in someList) { // ... } // Type of 'item' not clear.
var something = someObject.SomeProperty; // Type of 'something' not clear.
var something = someMethod(); // Type of 'something' not clear.

More legitimate uses of var are as follows:-

var l = new List<string>(); // Obvious what l will be.
var s = new SomeClass(); // Obvious what s will be.

Interestingly LINQ seems to be a bit of a grey area, e.g.:-

var results = from r in dataContext.SomeTable
              select r; // Not *entirely clear* what results will be here.

It's clear what results will be in that it will be a type which implements IEnumerable, however it isn't entirely obvious in the same way a var declaring a new object is.

It's even worse when it comes to LINQ to objects, e.g.:-

var results = from item in someList
              where item != 3
              select item;

This is no better than the equivilent foreach(var item in someList) { // ... } equivilent.

There is a real concern about type safety here - for example if we were to place the results of that query into an overloaded method that accepted IEnumerable<int> and IEnumerable<double> the caller might inadvertently pass in the wrong type.

var does maintain strong typing but the question is really whether it's dangerous for the type to not be immediately apparent on definition, something which is magnified when overloads mean compiler errors might not be issued when you unintentionally pass the wrong type to a method.

30 comments

@tvanfosson 2010-05-19 13:50:50

Var, in my opinion, in C# is a good thingtm. Any variable so typed is still strongly typed, but it gets its type from the right-hand side of the assignment where it is defined. Because the type information is available on the right-hand side, in most cases, it's unnecessary and overly verbose to also have to enter it on the left-hand side. I think this significantly increases readability without decreasing type safety.

From my perspective, using good naming conventions for variables and methods is more important from a readability perspective than explicit type information. If I need the type information, I can always hover over the variable (in VS) and get it. Generally, though, explicit type information shouldn't be necessary to the reader. For the developer, in VS you still get Intellisense, regardless of how the variable is declared. Having said all of that, there may still be cases where it does make sense to explicitly declare the type -- perhaps you have a method that returns a List<T>, but you want to treat it as an IEnumerable<T> in your method. To ensure that you are using the interface, declaring the variable of the interface type can make this explicit. Or, perhaps, you want to declare a variable without an initial value -- because it immediately gets a value based on some condition. In that case you need the type. If the type information is useful or necessary, go ahead and use it. I feel, though, that typically it isn't necessary and the code is easier to read without it in most cases.

@Steve Brouillard 2010-05-19 14:15:27

I agree overall. The key point here in my opinion is to be certain that intent is clear. If it isn't clear to the majority developers on the team, then it is detrimental, not helpful. That said, I personally am a HUGE fan of this, but have had to rein myself in a bit when other devs on my team have had trouble determining my intent. Go figure.

@BlueRaja - Danny Pflughoeft 2010-05-19 16:06:20

Eh, I find it easier to read when the type is on the left. Using ReSharper, I don't have to retype the type on the right anyways, so it doesn't bother me.

@tvanfosson 2010-05-19 16:11:15

@BlueRaja - I find that using good variable names usually eliminates the need to bother with the actual type anyway for understanding. Intellisense is still available on "var" defined variables, so I don't need to know the type to choose a method/property on it when coding.

@BlueRaja - Danny Pflughoeft 2010-05-19 16:34:31

It is not so much about when you are coding as it is when you have to read the code.

@tvanfosson 2010-05-19 17:31:36

@BlueRaja -- that's where using good variable names is important. You shouldn't need to know the type if the variable is named appropriately. If, for some reason, I do need to know the type, all I have to do is hover over the variable name to get it.

@AnthonyWJones 2010-05-21 08:45:37

I don't agree with this: "Because the type information is available on the right-hand side, in most cases" I would challenge whether that is really true. Looking through my teams codes we don't go around ensuring that the return type is verbatim in the method names. Using an expclicit type is more readable and more resilient to runtime bugs.

@tvanfosson 2010-05-21 10:46:25

@Anthony - 1) I never said that you couldn't use it in cases where the type information is valuable and isn't available. 2) Good naming, both with variable names and method names, is (from a reading/understanding perspective) more important than type information anyway. If you regularly need the type in addition to the variable/method names to make sense of the code you probably have bigger problems than using or not using var.

@AnthonyWJones 2010-05-21 11:11:12

I must just be on thick side then, I need to good Method and variable names and an understanding of the types being operated on to be able to properly understand the code I'm reading. I think you are right though it is symptomatic of bigger problems. One of trust. To be sure that the code is doing what it appears to be doing you need to be sure of the types being used.

@Adam Robinson 2010-05-19 13:49:26

Neither of those is absolutely true; var can have both positive and negative effects on readability. In my opinion, var should be used when either of the following is true:

  1. The type is anonymous (well, you don't have any choice here, as it must be var in this case)
  2. The type is obvious based upon the assigned expression (i.e. var foo = new TypeWithAReallyLongNameTheresNoSenseRepeating())

var has no performance impacts, as it's syntactic sugar; the compiler infers the type and defines it once it's compiled into IL; there's nothing actually dynamic about it.

@Ion Todirel 2010-05-19 13:59:21

agree on both, though I have long restrictions over the second case, if a type is that long the it's usually a generic type with lots of nested generic arguments, in that case a strongly typed "ShortType equivalent to TypeWithAReallyLongNameTheresNoSenseRepeating" makes more sense

@Steve Brouillard 2010-05-19 14:06:53

I have no desire to start a religious war, but I personnaly tend to disagree with Ion. I would much prefer a very long, but very precise type name (ala Uncle Bob Martin) than an abbreviated and possibly ambiguous shorter type name. I will add the caveat that I DON'T agree with artificially inflating the length of the name either. If 5 characters creates a concise name that clearly shows intent, then use 5 and not 25.

@Adam Robinson 2010-05-19 14:19:53

@Steve: I have to agree with you; creating a "short type" (which I assume you mean as inheriting from the specific generic type solely for the purpose of shortening the name) is not a good practice; it will require you to duplicate and pass through any constructors from the generic type, as well as preventing you from passing a different type that inherits from the generic type to the function. You're using inheritance like a typedef when it isn't.

@Kristoffer L 2010-05-19 14:46:03

@Steve: I guess you are refering to something like: List<KeyValuePair<string, Dictionary<MyClassName, AnotherComplexType>>> list = new List<KeyValuePair<string, Dictionary<MyClassName, AnotherComplexType>>>(); In this case, use I would use var and wrap the horrible mess of tags into a class that actually makes sense to me. var list = new ListOfComplexStuff(); I do agree with the answer that you should refrain from using var unless it does improve readabililty. Readability > Less keypresses.

@Joren 2010-05-19 15:02:16

Use var when the type is obvious? Maybe, but the true gain is when the type doesn't matter. If you're doing things like var customers = whatever; var query = from c in customers select stuff it doesn't matter what the exact type of 'customers' is. It's obvious how you can use it, and that's enough. And if the actual type is cumbersome, it's worthwhile to suppress it.

@Adam Robinson 2010-05-19 15:42:47

@Kristoffer: I can understand wanting to eliminate the mess of tags, but wrapping them into a class is not (IMO) an acceptable alternative, as you then cut off the possibility of any other (legitimate) child class of that generic type from being a valid parameter. I would rather use an using ShortType = LongGenericType<A,B,C> directive at the top of a file, since that gives the same readability, doesn't require that you recreate the constructors, and doesn't eliminate child classes from being candidates.

@Adam Robinson 2010-05-19 15:43:49

@Joren: The true gain is when it's more readable. If the type truly doesn't matter, then it's probably more readable. If the type matters but is obvious from the inferrence source, then it's probably more readable.

@Ion Todirel 2010-05-19 18:44:34

@Steve Brouillard, Steve, that's actually my reason as well, but I prefer a shorter name and the type to complement the variable name, e.g. var iPhoneApplication = ..., vs. IPhoneApplication app =... .

@JulianR 2010-05-19 18:58:02

@Joren - Exactly. I shouldn't care what type a variable of customer is. The name is descriptive enough to know what you can roughly do with it.

@Joren 2010-05-19 19:58:25

@Adam Robinson: You are right, readability is the end goal. And when the type is obvious, indeed var can improve things. My point shouldn't be to the exclusion of yours – I definitely agree with your entire answer – I just used yours as a hook-in for adding a third point. 'True gain' was an exaggeration.

@Steve Brouillard 2010-05-19 22:24:31

I think most of us commenting here are on the same page.

@Peter Mortensen 2010-11-28 09:23:29

@Adam Robinson: "infersthe" -> "infers the"

@Chris S 2009-01-31 11:54:34

I don't use var as it goes against the roots of C# - C/C++/Java. Even though it's a compiler trick it makes the language feel like it's less strongly typed. Maybe 20+ years of C have engrained it all into our (the anti-var people's) heads that we should have the type on both the left and right side of the equals.

Having said that I can see its merits for long generic collection definitions and long class names like the codinghorror.com example, but elsewhere such as string/int/bool I really can't see the point. Particularly

foreach (var s in stringArray)
{

}

a saving of 3 characters!

The main annoyance for me is not being able to see the type that the var represents for method calls, unless you hover over the method or F12 it.

@C. A. McCann 2012-11-09 17:30:59

Heh. If C++/Java/etc. are your idea of what a strongly/statically typed language should be like, then you've never used a language with a real static type system--many of which have far more type inference than C# and far stronger type guarantees than the languages you mention. This reaction to var is cargo cult programming, pure and simple.

@Chris S 2012-11-10 23:06:08

@C.A.McCann are you saying types are cargo cult programming? I'm confused. var was introduced into C# in 3.0 alongside LINQ which was arguably its main purpose, there was a good 5 years of C# development I (and other moaners like me) did without it.

@C. A. McCann 2012-11-10 23:15:06

Static types are great, having to write out types for every declaration is mostly useless. Type inference has been around for longer than C# itself has, in languages that have real static types, not the crippled garbage you get in C-style languages.

@Matt Hamilton 2008-09-03 11:53:07

I still think var can make code more readable in some cases. If I have a Customer class with an Orders property, and I want to assign that to a variable, I will just do this:

var orders = cust.Orders;

I don't care if Customer.Orders is IEnumerable<Order>, ObservableCollection<Order> or BindingList<Order> - all I want is to keep that list in memory to iterate over it or get its count or something later on.

Contrast the above declaration with:

ObservableCollection<Order> orders = cust.Orders;

To me, the type name is just noise. And if I go back and decide to change the type of the Customer.Orders down the track (say from ObservableCollection<Order> to IList<Order>) then I need to change that declaration too - something I wouldn't have to do if I'd used var in the first place.

@Jon Tackabury 2008-10-21 18:30:46

I like having the explicit type in front of me when I'm reading code. How do I know what "cust.Orders" is here without the type? Yes, I could hover my mouse over to find out, but why should I have to? :)

@Matt Hamilton 2008-10-21 19:53:09

But the point is that in general it doesn't matter. Provided cust.Orders is something you can enumerate (eg foreach over) then it doesn't matter what type it is. The extra code just gets in the way of reading the intent.

@John Bubriski 2009-04-15 00:34:14

Yeah I frequently end up changing generics when doing some rough outlines.

@GrahamS 2009-04-15 10:03:25

But if you only require that cust.Orders is "something you can enumerate" then doesn't declaring it as an IEnumerable<Order> make that requirement explicit and clear? Declaring it as var means you effectively lose that requirement.

@Steven Evers 2009-05-19 19:26:59

I think this is a bit of a simplification of the issue. True, that if all you want to do is iterate over the list, then it doesn't matter... but, in your example, if it's BindingList<Order> then it tells you, immediately that it will support binding to a UI control without trouble - which is important info imo.

@krdluzni 2009-09-02 13:32:37

If you're really in a situation where listing what interface you're getting is 'just noise,' then you probably don't need to be getting that interface. But you should be using the object in code later on, so clearly the interface is not irrelevant. (Is it strange if I think like this?)

@krystan honour 2009-10-15 08:37:00

Whilst it is a personal decision I do not agree that the type name is just noise, it is all about maintainability for me, long after you are gone lesser mortals will have to read your code, using var where you CAN use a strong type name is in my opinion wrong. I didn't used to beleive that but after a while of using the style you have above I became convinced.

@Rune FS 2010-02-04 22:08:00

@jon and how would IEnumerbal orders = cust.Orders foreach(var order in orders) make a difference? the only thing IEnumerable says is that you can put it in a foreach but you already knew that from the line below

@Joe 2010-04-29 05:45:55

"the only thing IEnumerable says is that you can put it in a foreach" - it also expresses the intention that the only thing you can do is enumerate. Using var gives access to and intellisense for public members of the concrete collection type.

@chiccodoro 2010-08-13 09:48:02

@Joe - And if you want to use any of these public members, which are not part of IEnumerable, then it would help a reader much to explicitly declare the variable using that particular type.

@Dan Abramov 2011-06-27 19:48:16

I just realized var changed the way I write code. I started writing faster, in a good way.

@Dexter 2008-09-17 01:08:18

We've adopted the ethos "Code for people, not machines", based on the assumption that you spend multiple times longer in maintenance mode than on new development.

For me, that rules out the argument that the compiler "knows" what type the variable is - sure, you can't write invalid code the first time because the compiler stops your code from compiling, but when the next developer is reading the code in 6 months time they need to be able to deduce what the variable is doing correctly or incorrectly and quickly identify the cause of issues.

Thus,

var something = SomeMethod();

is outlawed by our coding standards, but the following is encouraged in our team because it increases readability:

var list = new List<KeyValuePair<string, double>>();
FillList( list );
foreach( var item in list ) {
   DoWork( item ); 
}

@Thanatos 2010-05-28 00:21:27

I've found that ("Code for people, not machines") to be an excellent guideline - following it can result in better code and helps avoid premature optimization.

@TTT 2010-10-16 03:51:48

I don't get var list = new KeyValuePair<string, double>? For me a list can have more than on thing.

@user1068352 2012-12-12 11:42:18

"Code for people, not machines" - amen.

@Wray Smallwood 2010-03-11 18:27:24

For the afficionados that think var saves time, it takes less keystrokes to type:

StringBuilder sb = new StringBuilder();

than

var sb = new StringBuilder();

Count em if you don't believe me...

19 versus 21

I'll explain if I have to, but just try it... (depending on the current state of your intellisense you may have to type a couple more for each one)

And it's true for every type you can think of!!

My personal feeling is that var should never be used except where the type is not known because it reduces recognition readabiltiy in code. It takes the brain longer to recognize the type than a full line. Old timers who understand machine code and bits know exactly what I am talking about. The brain processes in parallel and when you use var you force it to serialize its input. Why would anyone want to make their brain work harder? That's what computers are for.

@ljs 2010-03-12 12:59:57

I find the repetition of stringBuilder sb = new StringBuilder() messy and longer to clearly recognise. It's extra noise. The problem is, determining what does and doesn't constitute extra intellectual effort to understand some code is pretty subjective!

@Gabriel Magana 2010-05-19 20:23:26

"var should never be used except where the type is not known..." - You can ALWAYS know the type, as does the compiler. This is not dynamic typing, it just lets the compiler determine the type for you. But the type is never an unknown.

@Muhammad Atif Agha 2011-11-28 09:59:08

Local variables can be given an inferred "type" of var instead of an explicit type. The var keyword instructs the compiler to infer the type of the variable from the expression on the right side of the initialization statement.

// z is compiled as an int

var z = 100;

// s is compiled as a string below

var s = "Hello";

// a is compiled as int[]

var a = new[] { 0, 1, 2 };

// expr is compiled as IEnumerable // or perhaps IQueryable

var expr =
    from c in customers
    where c.City == "London"
    select c;

// anon is compiled as an anonymous type

var anon = new { Name = "Terry", Age = 34 };

// list is compiled as List

var list = new List<int>();

var can only be used when a local variable is declared and initialized in the same statement; the variable cannot be initialized to null, or to a method group or an anonymous function.

var cannot be used on fields at class scope.

Variables declared by using var cannot be used in the initialization expression. In other words, this expression is legal: int i = (i = 20); but this expression produces a compile-time error: var i = (i = 20);

Multiple implicitly-typed variables cannot be initialized in the same statement.

If a type named var is in scope, then the var keyword will resolve to that type name and will not be treated as part of an implicitly typed local variable declaration.

@user915331 2011-11-23 03:04:12

var is like the dotted spaces in kids' books where kids have to fill it. Except in this case the Compiler will fill it with the right type which is usually written after the = sign.

@Andrew Barber 2011-11-24 23:13:23

Wow, really? and no, you know what I'm talking about.

@user915331 2011-11-25 03:58:34

Ok, you are the prof. and I am just a student. so I wont argue. But if you like you can ask MS to remoev the var keyword if it bothers you a lot. As you always say dear Andrew: "var must die".

@Andrew Barber 2011-11-25 04:01:09

Thatls not at all what I'm talking about.

@user915331 2011-11-25 04:05:09

You mean the downvoting?

@Andrew Barber 2011-11-25 04:06:24

Kinda backfired on ya, didn't it?

@user915331 2011-11-25 04:08:50

Not really Andrew. My Rep. was 172 or so.. FYI, the downvote you give me was kinda unfair...

@Andrew Barber 2011-11-25 04:10:34

@user915331 2011-11-25 04:11:14

for the record, I was checking your answers and to be fair you know a lot. But you are arrogant.. so the formula is: (knowledge + arrogance) = 0 ;)

@Andrew Barber 2011-11-25 04:37:11

Thanks for chatting with me and talking it all out!

@Mel 2011-11-21 05:41:27

var is the way to deal with anonymous types, whether from LINQ statements or not. Any other use is heavily dependent on who will read your code and what guidelines are in place.

If you are the only audience or your audience is comfortable with using var or is very familiar with your code then I guess it doesn't matter. If you use it like: var s = new SqlConnection() then it largely doesnt matter and probably improves code readability. If people aren't too picky and its okay for them to do a little work to know the type when its not apparent (which is not needed in most cases, how you use it in the following statements would usually explain everything) then its alright.

But if you have picky, close-minded teammates who love to whine or if your company's design guidelines specifically forbid using var when the type is not obvious then you will most likely meet heavy opposition.

If using var makes your code insanely difficult to read, you will probably get shot by using var even if its probably your app design that is to blame.

If var introduces ambiguity (sort of like your IEnumerable/IEnumerable example), just don't use it and be explicit. But var does have its conveniences and in some cases, IMHO, even improves readabilty by reducing clutter.

@Colin Desmond 2009-06-09 19:10:37

Given how powerful Intellisense is now, I am not sure var is any harder to read than having member variables in a class, or local variables in a method which are defined off the visible screen area.

If you have a line of code such as

IDictionary<BigClassName, SomeOtherBigClassName> nameDictionary = new Dictionary<BigClassName, SomeOtherBigClassName>();

Is is much easier or harder to read than:

var nameDictionary = new Dictionary<BigClassName, SomeOtherBigClassName>();

@Finglas 2009-06-09 19:12:26

I didn't actually consider this, at it seems from the other question that is a fairly strong point for one other time to use it.

@mqp 2009-06-09 19:13:17

That was basically the only reason they implemented it (besides being able to declare anonymous types, but they could have made "var" a special keyword that was only for anonymous types.)

@Dustman 2008-09-18 20:22:53

From Eric Lippert, a Senior Software Design Engineer on the C# team:

Why was the var keyword introduced?

There are two reasons, one which exists today, one which will crop up in 3.0.

The first reason is that this code is incredibly ugly because of all the redundancy:

Dictionary<string, List<int>> mylists = new Dictionary<string, List<int>>();

And that's a simple example – I've written worse. Any time you're forced to type exactly the same thing twice, that's a redundancy that we can remove. Much nicer to write

var mylists = new Dictionary<string,List<int>>();

and let the compiler figure out what the type is based on the assignment.

Second, C# 3.0 introduces anonymous types. Since anonymous types by definition have no names, you need to be able to infer the type of the variable from the initializing expression if its type is anonymous.

Emphasis mine. The whole article, C# 3.0 is still statically typed, honest!, and the ensuing series are pretty good.

This is what var is for. Other uses probably will not work so well. Any comparison to JScript, VBScript, or dynamic typing is total bunk. Note again, var is required in order to have certain other features work in .NET.

@Dave 2008-10-17 20:28:16

I find Lippert's argument odd. No one types the second class name, they let Intellisense write it for them, but then he turns around and claims that var is better because the compiler/Intellisense works it out. You can't have it both ways!

@Dustman 2009-03-09 05:19:50

The C# team doesn't control intellisense, they control the compiler. In any event that's not the main issue. I don't think var would have made the 100 points on saving typing alone.

@Piotr Perak 2011-10-20 20:45:09

@Dustman: var doesn't save typing at all. It makes you write more!

@Will Marcouiller 2010-05-19 15:20:25

var is a placeholder introduced for the anonymous types in C# 3.0 and LINQ.

As such, it allows writing LINQ queries for a fewer amount of columns within, let's say, a collection. No need to duplicate the information in memory, only load what's necessary to accomplish what you need to be done.

The use of var is not bad at all, as it is actually not a type, but as mentioned elsewhere, a placeholder for the type which is and has to be defined on the right-hand side of the equation. Then, the compiler will replace the keyword with the type itself.

It is particularly useful when, even with IntelliSense, the name of a type is long to type. Just write var, and instantiate it. The other programmers who will read your code afterward will easily understand what you're doing.

It's like using

public object SomeObject { get; set; }

instead of:

public object SomeObject {
    get {
        return _someObject;
    } 
    set {
        _someObject = value;
    }
}
private object _someObject;

Everyone knows what's the property's doing, as everyone knows what the var keyword is doing, and either examples tend to ease readability by making it lighter, and make it more pleasant for the programmer to write effective code.

@David Mårtensson 2010-10-25 10:01:27

With LINQ another very good reason to use var is that the compiler can optimize the query much more.

If you use a static list to store the result it will execute where you assign it to the list but with var it can potential merge the original query with later queries in the code to make more optimized queries to the database.

I had an example where I pulled some data in a first query and then looped over and requested more data to print out a table.

LINQ merges these so that the first only pulled the id.

Then in the loop it added an extra join I had not done there to fetch the data I had included in the original.

When tested this proved much more efficient.

Had we not used var it had made the queries exactly as we had written them.

@ljs 2008-09-03 13:16:09

@Keith -

In your comparison between IEnumerable<int> and IEnumerable<double> you don't need to worry - if you pass the wrong type your code won't compile anyway.

That isn't quite true - if a method is overloaded to both IEnumerable<int> and IEnumerable<double> then it may silently pass the unexpected inferred type (due to some other change in the program) to the wrong overload hence causing incorrect behaviour.

I suppose the question is how likely it is that this sort of situation will come up!

I guess part of the problem is how much confusion var adds to a given declaration - if it's not clear what type something is (despite being strongly typed and the compiler understanding entirely what type it is) someone might gloss over a type safety error, or at least take longer to understand a piece of code.

@Martin Olsen 2010-10-26 06:00:34

I'm fairly new in the C# world, after a decade as a Java professional. My initial thought was along the lines of "Oh no! There goes type safety down the drain". However, the more I read about var, the more I like it.

1) Var is every bit as type safe as an explicitly declared type would be. It's all about compile time syntactic sugar.

2) It follows the principle of DRY (don't repeat yourself). DRY is all about avoiding redundancies, and naming the type on both sides is certainly redundant. Avoinding redundancy is all about making your code easier to change.

3) As for knowing the exact type .. well .. I would argue that you always have a general idea is you have an integer, a socket, some UI control, or whatever. Intellisense will guide you from here. Knowing the exact type often does not matter. E.g. I would argue that 99% of the time you don't care if a given variable is a long or an int, a float or a double. For the last 1% of the cases, where it really matters, just hover the mouse pointer above the var keyword.

4) I've seen the ridiculous argument that now we would need to go back to 1980-style Hungarian warts in order to distinguish variable types. After all, this was the only way to tell the types of variables back in the days of Timothy Dalton playing James Bond. But this is 2010. We have learned to name our variables based upon their usage and their contents and let the IDE guide us as to their type. Just keep doing this and var will not hurt you.

To sum it up, var is not a big thing, but it is a really nice thing, and it is a thing that Java better copy soon. All arguments against seem to be based upon pre-IDE fallacies. I would not hesitate to use it, and I'm happy the R# helps me do so.

@user418243 2010-08-12 09:53:44

what most are ignoring:

var something = new StringBuilder(); 

isn't normally typed as fast as

StringBuilder something = KEY'TAB'();

@GiddyUpHorsey 2010-08-12 10:20:00

Yeah, but you duplicate "StringBuilder". Having it twice makes for more code. I like var because it makes code shorter, less information, easier to read.

@Chris S 2010-08-13 07:32:20

...and more like Javascript. var was intended for LINQ, abusing it should be punished by removing intellisense from your Visual Studio for a week.

@Glenn Doten 2010-07-29 21:14:39

If you are lazy and use var for anything other than anonymous types, you should be required to use Hungarian notation in the naming of such variables.

var iCounter = 0;

lives!

Boy, do I miss VB.

@user395760 2010-07-29 21:27:11

-1: Digging out old question just to flame agains type interference, without reason - not even a subjective or arguably stupid reason, just no reason at all. The fact that you call this abomination Hungarian notation (I don't care some calls it so, in my book Hungarian notation still means incorporating the variable's purpose in the name, not its exact type) only makes it feel more appropriate.

@Glenn Doten 2010-07-30 12:26:05

Sorry you feel that way. In my experience, Hungarian notation has always meant the type of the variable is the prefix; the part of the name after the type prefix describes the purpose of the variable. You think Hungarian notation means you prefix and suffix the name with its purpose? Now there's some of that redundancy that has been brought up in this thread! Hungarian notation has always been about using prefixes to give the reader of the code an idea of the type of the variable. And this is something that those who use var need to do! Using var for non-anon types is indeed an "interference."

@user395760 2010-07-30 21:13:03

Type inference that is, of course - silly typo. But you still don't give anything like a reason why type interference is a bad thing™. Concerning Hungarian: Ask Wikipedia. It has a nice example somewhere, the prefix i: You'd use it a "integer", while the "apps Hungarian notation", as wiki calls it, uses it for "index" - the latter contains much more semantic information and actually tells you something the type system can't tell you, while the first is redunant with a halfway decent IDE.

@Glenn Doten 2010-07-31 11:59:44

Good point. I should have used "var intCounter = 0;" in my example (sorry, I haven't used VB in quite a while). But the type of Hungarian I was referring to should have been obvious from the VB context. Perhaps my use of sarcasm to get across my point of why using a var for anything other that anon types did not translate well (although "lazy" is certainly an explicit reason). And if you don't understand why I think it is pure laziness to use var for anything but anon types, well, just read some of the other replies to this thread. And remember, not everyone uses (or has) an IDE.

@Igor Brejc 2010-07-20 09:14:43

One good argument why vars should not be used as a mere "typing shortcut", but should instead be used for scenarios they were primarily designed for: Resharper (at least v4.5) cannot find usages of a type if it is represented as a var. This can be a real problem when refactoring or analyzing the source code.

@Benjol 2009-04-27 09:09:18

Arriving a bit late at this discussion, but I'd just like to add a thought.

To all those who are against type inference (because that's what we're really talking about here), what about lambda expressions? If you insist on always declaring types explicitly (except for anonymous types), what do you do with lambdas? How does the "Don't make me use mouseover" argument apply to var but not to lambdas?

UPDATE

I've just thought of one argument against 'var' which I don't think anyone has mentioned yet, which is that it 'breaks' "Find all references", which could mean (for example) that if you were checking out usage of a class before refactoring, you would miss all the place where the class was used via var.

@Benjol 2009-04-27 12:57:09

Wonder how many of the pro-var people have been 'polluted' by F#? :)

@Joel Mueller 2009-12-09 17:44:23

It's true. I often find myself wishing the C# type inference was as good as that in F#.

@Ion Todirel 2010-05-19 13:48:33

It's not bad, it's more a stylistic thing, which tends to be subjective. It can add inconsistencies, when you do use var and when you don't.

Another case of concern, in the following call you can't tell just by looking at the code the type returned by CallMe:

var variable = CallMe();

That's my main complain against var.

I use var when I declare anonymous delegates in methods, somehow var looks cleaner than if I'd use Func. Consider this code:

var callback = new Func<IntPtr, bool>(delegate(IntPtr hWnd) {
   ...
});

EDIT: Updated the last code sample based on Julian's input

@Randolpho 2010-05-19 13:53:17

But do you really need to know the type right there at that line? You know that CallMe returns something; isn't it enough to know that a local variable named variable is created? Unless you expand your example, this isn't a very solid complaint, IMO.

@Ion Todirel 2010-05-19 13:56:42

knowing the type lets you make more sense out of any code below the initialization, you automatically know "that code can call that or that", and by having a nice name for the variable you make sense of the code easier

@Randolpho 2010-05-19 14:00:27

But you don't need to know the type in order to read the code. If you see, for example, variable.MyMethod(), you know that the code calls the MyMethod method on whatever type variable happens to be. You don't need to know what MyMethod does at that point, because what you're only concerned with is the fact that the code calls it. Let's assume that you're reading the code for the Very First Time (tm). Even if you knew the type of variable at the declaration, odds are you don't know what that type is or does. You have to go look it up either way, so why be verbose about it?

@Ion Todirel 2010-05-19 14:08:32

It's not about not being verbose, it's about not letting the compiler do the syntax sugar for you. Consider this: var getter..., now this Func<object> getter..., with the second you know you don't have to provide any parameters and what it returns. You know from the start "what to do" and can make decisions faster, when designing something or refactoring. Having all the information at hand is more important than a few more characters. This only can be appreciated when you're working with lots of code.

@Rubys 2010-05-19 14:15:41

Since we are all talking about visual studio anyway, what's the big deal about hovering your mouse over the variable for a second and just seeing what type is it? Much better than running to the declaration anyway.

@Ion Todirel 2010-05-19 14:19:58

Agree and don't, it's subjective... :)

@Randolpho 2010-05-19 14:24:38

On the contrary, I work with lots of code all the time, and I always prefer var. In your Func<object> example, you can tell from the context of the code (based on the fact that it is called later using getter()) that it's a callable item, either a Func or a delegate. The point is that you can tell from the context, so it's not necessary to have it declared upfront. Planning a refactor is different; yes, you need all the infos when you're planning something like that. But you can obtain it by other means, particularly intellisense, so you don't need it written down right there.

@Danko Durbić 2010-05-19 14:32:44

Generic variable and function names (variable, CallMe) make bad examples. However, if CallMe() was a function in some kind of a "phone application", then var call = CallMe(); .... call.HangUp(); would make much more sense.

@Powerlord 2010-05-19 14:49:31

@Randolpho: "what's the big deal about hovering your mouse over the variable for a second and just seeing what type is it?" It adds time to the maintenance overhead... plus one second is only the hover time rather than counting the keyboard to mouse context switch. I don't know about you, but I work with a deadline. Every time I have to hover over a variable to find out what type it is, is time that I could have better spent fixing a problem.

@Randolpho 2010-05-19 15:04:51

@R. Bemrose: If you're reading the code For The First Time (tm), you'll do a lot better with Right-Click->Go To Definition (F12, since you're apparently a keyboard jockey like me) than a mouse hover; you'll need to anyway if it's a custom type because you'll need to eventually analyze the type. But you don't need a type declaration for the method you're analyzing, since at that point you're more interested in how the type is used than what it actually is. And for 99.9% of the cases where the type is a core framework type, you can figure out what the type is by how it's used.

@tvanfosson 2010-05-19 17:29:59

I'm with @Danko -- if you're naming variables variable, you've got bigger readability problems than whether or not the var keyword is appropriate. When an appropriate variable name is used, you rarely need to know the actual type to understand what the code does.

@JulianR 2010-05-19 18:09:59

Your callback example is not valid C#.

@Ion Todirel 2010-05-19 18:41:24

@Julian, thanks, I wrote it in a hurry, updated. But you could see the point as it was

@Julie in Austin 2010-05-19 16:27:35

If you know the type, use the type. If you don't know the type, why not? If you can't know the type, that's okay -- you've found the only valid use.

And I'm sorry, but if the best you can do is "it makes the code all line up", that's not a good answer. Find a different way to format your code.

@Jerry Liu 2010-05-19 16:03:14

var is good as it follows the classic DRY rule, and it is especially elegant when you indicate the type in the same line as declaring the variable. (e.g. var city = new City())

@Joshua 2010-05-19 15:10:59

"The only thing you can really say about my taste is that it is old fashioned, and in time yours will be too." -Tolkien.

@Andrew Lewis 2010-05-19 15:09:12

It's not wrong, but it can be inappropriate. See all the other responses for examples.

var x = 5; (bad)

var x = new SuperDooperClass(); (good)

var x = from t in db.Something select new { Property1 = t.Field12 }; (better)

@stormianrootsolver 2010-05-19 15:05:52

Don't use that, makes your code unreadable.

ALWAYS use as strict typing as possible, crutches only makes your life hell.

@Konrad Rudolph 2010-05-19 15:18:12

var is strict typing. It’s not a crutch in any sense. And it doesn’t make the code unreadable.

@Mel 2011-11-21 05:51:55

it actually improves readability in some cases: using (var con = new SqlConnection()) is easier on the eyes than having to type the type twice

@kervin 2010-05-19 14:51:25

Eric's answer here...

Namespace scoped aliases for generic types in C#

is related.

Part of the issue is that there is no strongly typed aliasing in C#. So many developers use var as a partial surrogate.

@Christopher Barber 2010-05-19 14:21:45

Apart from readability concerns, there is one real issue with the use of 'var'. When used to define variables that are assigned to later in the code it can lead to broken code if the type of the expression used to initialize the variable changes to a narrower type. Normally it would be safe to refactor a method to return a narrower type than it did before: e.g. to replace a return type of 'Object' with some class 'Foo'. But if there is a variable whose type is inferred based on the method, then changing the return type will mean that this variable can longer be assigned a non-Foo object:

var x = getFoo(); // Originally declared to return Object
x = getNonFoo();

So in this example, changing the return type of getFoo would make the assignment from getNonFoo illegal.

This is not such a big deal if getFoo and all of its uses are in the same project, but if getFoo is in a library for use by external projects you can no longer be sure that narrowing the return type will not break some users code if they use 'var' like this.

It was for exactly this reason that when we added a similar type inferencing feature to the Curl programming language (called 'def' in Curl) that we prevent assignments to variables defined using this syntax.

@Christian Specht 2010-05-19 14:09:30

I only use var when it's clear to see what type is used.

For example, I would use var in this case, because you can see immediately that x will be of the type "MyClass":

var x = new MyClass();

I would NOT use var in cases like this, because you have to drag the mouse over the code and look at the tooltip to see what type MyFunction returns:

var x = MyClass.MyFunction();

Especially, I never use var in cases where the right side is not even a method, but only a value:

var x = 5;

(because the compiler can't know if I want a byte, short, int or whatever)

@JulianR 2010-05-19 18:52:59

If the right hand side isn't clear enough to justify the use of var, then var isn't the problem: the right hand side is the problem. It's not descriptive enough. Customer c = GetContext() is still unclear and no better than using var.

@Guffa 2010-05-19 13:51:38

If someone is using the var keyword because they don't want to "figure out the type", that is definitely the wrong reason. The var keyword doesn't create a variable with a dynamic type, the compiler still has to know the type. As the variable always has a specific type, the type should also be evident in the code if possible.

Good reasons to use the var keyword are for example:

  • Where it's needed, i.e. to declare a reference for an anonymous type.
  • Where it makes the code more readable, i.e. removing repetetive declarations.

Writing out the data type often makes the code easier to follow. It shows what data types you are using, so that you don't have to figure out the data type by first figuring out what the code does.

@Jeff Sternal 2010-05-19 13:48:28

Deleted for reasons of redundancy.

vars are still initialized as the correct variable type - the compiler just infers it from the context. As you alluded to, var enables us to store references to anonymous class instances - but it also makes it easier to change your code. For example:

// If you change ItemLibrary to use int, you need to update this call
byte totalItemCount = ItemLibrary.GetItemCount();

// If GetItemCount changes, I don't have to update this statement.
var totalItemCount = ItemLibrary.GetItemCount();

Yes, if it's hard to determine a variable's type from its name and usage, by all means explicitly declare its type.

Related Questions

Sponsored Content

27 Answered Questions

[SOLVED] Get int value from enum in C#

  • 2009-06-03 06:46:39
  • jim
  • 1423882 View
  • 1708 Score
  • 27 Answer
  • Tags:   c# enums casting int

10 Answered Questions

[SOLVED] What are the correct version numbers for C#?

22 Answered Questions

[SOLVED] What is the best way to give a C# auto-property an initial value?

61 Answered Questions

[SOLVED] How do I calculate someone's age in C#?

  • 2008-07-31 23:40:59
  • Jeff Atwood
  • 576734 View
  • 1764 Score
  • 61 Answer
  • Tags:   c# .net datetime

65 Answered Questions

[SOLVED] What is the difference between String and string in C#?

39 Answered Questions

33 Answered Questions

[SOLVED] What's the difference between using "let" and "var"?

17 Answered Questions

[SOLVED] What is the yield keyword used for in C#?

  • 2008-09-02 13:15:24
  • Herms
  • 300210 View
  • 785 Score
  • 17 Answer
  • Tags:   c# yield

Sponsored Content