Linq Specifiqs – var

So this is the start of a series of posts that will dive a little deeper into the new C# 3.0 features.  My previous posts covered an overall view of what we were doing with the language as well as the Linq initiative, but didn't delve deep into the nitty gritty behind everything.  Hopefully through these posts i can make each individual facet of the future work clearer.  I'll also bring up open questions we still have and my own personal thoughts on the where we are now and where i hope to be.

It should be noted that what we have shown at the PDC is just a *preview*.  Nothing is set in stone, and it's quite likely that things will definitively change before the final future release.  It's my hope that by communicating with the developer community we can end up creating a better C# 3.0 for everyone.

So, i'm going start with the "var" feature.  The full name is actually "Implicitly Typed Local Variables", but that's quite a mouthful, so we'll just be calling it the "var" feature for now.  So what is this feature?  Well, as the full name would imply, it's a feature that allows you to declare a local variable without having to explicitly declare its type.  For example, say you currently had the following code within some member:

int i = 5;
string s = "Hello";
double d = 1.0;
int[] numbers = new int[] {1, 2, 3};
Dictionary<int,Order> orders = new Dictionary<int,Order>();

You could now write that as:

var i = 5;
var s = "Hello";
var d = 1.0;
var numbers = new int[] {1, 2, 3};
var orders = new Dictionary<int,Order>();

The important thing to realize is that "var" does *not* mean "object".  In fact, both code samples above will compile to the *exact* same thing. 

So how does this work?  Well, unlike a regular local variable declaration, a "var" declaration is required to have not just a name, but also an initializer as well.  The compiler will then figure out the type of the initializer expression (which is well defined as per the rules of the C# language) and treat the declaration as if you'd used that type as the local variable type.  So if you then try to type:

s.IndexOf('{'); //This will compile.  's' is a string, and string has an IndexOf(char) method on it.
s.FoobyBoob(); //This won't compile. string doesn't have 'FoobyBoob' method

To make things clear.  "var" isn't some "variant" type (although the name is certainly unfortunate), and it doesn't imply some sort of "dynamic" typing system going on.  Your code is statically checked exactly as it would be if you had explicitly written down the type.

Now, right now "var" is just for local variables.  Why not allow it for something like a method parameter declaration?  Well, say you had the following:

interface IExample {
void ShowOff(var parameter); //what type would this be? It has no initializer to determine the type from

class OtherExample {
void Demonstration(var parameter) { //what type would this be?
parameter.Convert(); //we can't figure out what type it should be based on what we see here.

In the first case, there's simply nothing we could do.  Without any sort of code in scope that uses "parameter" we couldn't hope to determine what its type was.  In the second case, it's possible we could try to figure out the type somehow, but it would probably be enormously complex and confusing (And often we'd still be unable to figure it out).  By limiting to local variables that *have* to have an initializer, we ensure a feature that will be usable and available in pretty all places where local variables are allowed..

So... um... neat... but why would i want that?

That's a fantastic question.  Let's start by referring to some shortcomings/negatives first.  While implicitness can be quite handy for writing code, it can make things quite difficult when trying to just read code.  In all the above examples it's fairly easy to determine what the type of each of the variables is.  That's because you have either a nice primitive that you can look at, or the call to some constructor which you can then look directly at to figure out the type of variable.  But it's not always that simple.  What if you were to have:

var lollerskates = GetSkates(these, parameters, will, affect, overload, resolution);

Now what do you do?  As i said before the type of the variable will be statically determined by the compiler using the expression binding rules that are spelled out in detail in the C# specification.  But that in itself is an extraordinary problem.  There is a huge number of binding rules, and some of them (like generic type inference) are quite complex.  Keeping all those rules in your head and correctly trying to apply them on-the-fly in order to just comprehend what your code means sounds like a rather onerous burden to put on you.  In effect we'd be asking you to do the compilers job just so you could answer the question "is lollerskates an IEnumerable or an IList??"

On the other hand, var does make other things nicer.  For one thing, it avoids some pretty ugly duplication that arises when you start to write heavily genericized code.  Instead of needing to write:

Dictionary<IOptional<IList<string>>,IEnumerable<ICollection<int>>> characterClasses =
new Dictionary<IOptional<IList<string>>,IEnumerable<ICollection<int>>>()

you can now write:

var characterClasses = new Dictionary<IOptional<IList<string>>,IEnumerable<ICollection<int>>>()

There's a heck of a lot of duplication that you can now cut out.  It cleans up your code *and* makes it more readable (IMO).  Two plusses that are always welcome in my book.  Another benefit is if you have code like this:

object o = ExistingMethod();


object ExistingMethod() { ... }

If you then update ExistingMethod like so:

string ExistingMethod() { ... }

Well, your code still compiles, however if you want to take advantage of the fact that ExistingMethod returns "string" (i.e. to call some method like IndexOf on them) you'll have to update all your declarations that call from "object" to "string".  If you had declared it as:

var o = ExistingMethod();

then you would only have to update one location while still being able to take advantage of that redefinition everywhere.

Ok.  Well, those both seem somewhat *meh*'ish.  Convenient sure, but worth the potential negatives in code readability?  With C# 2.0 as it exists today... probably not.  But with some of the Linq work we have coming up, then the picture changes quite a bit.  Let's start by looking at a potential way you can write queries in C# 3.0:

   var q =
from c in customers
where c.City == "Seattle"
select new {
Orders =
from o in c.Orders
where o.Cost > 1000
select new { o.Cost, o.Date }

In this case we're generating a hierarchical anonymous type (which i'll go in depth on in a future article).  Say we didn't have "var", but we *did* have some hypothetical syntax for expressing an anonymous type.  We'd end up having to write the following:

  IEnumerable<class { string Name; IEnumerable<class { int Cost; DateTime Date }> Orders }> q =
from c in customers
where c.City == "Seattle"
select new {
Orders =
from o in c.Orders
where o.Cost > 1000
select new { o.Cost, o.Date }

Good golly!  That's a lot to type!  As with the "Dictionary" example above, you end up with a declaration with a lot of duplication in it.  Why should i have to fully declare this hierarchical type when the structure of the type i'm creating is fairly clear from the query initializing it.  You could make things easier for yourself by defining your own types ahead of time instead of using anonymous types, but that would make the act of projecting in a query far less simple than what you can do with anonymous types.   Of course, if you want to do this, you're completely able to do so while being fully able to work within Linq system.  And, because this seems like a feature with it's own plusses/minuses, and because it seems like people will want to move back and forth between implicit/explicit types depending on the code they're writing, it will make a lot of sense for us to provide user tools for this space.  Some sort of refactoring like "Reify variables".  Or... since people won't know what the heck that means: "make variable implicit/explicit."   🙂

So what do you think?  Are there things you do/don't like about "var"?  Personally, i think the name is somewhat of a problem.  C++ is introducing a similar concept, while calling it "auto".  I'm partial to that, but leaning more to making "infer" a keyword itself.  I think writing down "infer a = "5" reads very well and helps alleviate confusion issues that might arise with "var".

Comments (60)
  1. damien morton says:

    Var certainly is confusing, but only to people who are coming from languages with a variant type. Other people will get it in short order, and even variant type afficionados will learn it pretty quickly.

    The only consise alternative that makes any sense to me (but i dont know what the VB connotations are, and frankly, you cant be forced to tiptoe around VB-isms):

    let c = new{X=1,Y=2};

    Something that would be nice to be able to do:

    static T Foo<S,T>(S input)


    return new{X=input,Y=3};


    That is, allowing anonymous return types to participate in generic binding. In the alpha, this is an error.

    Of course, this might also work:

    static var Foo<S>(S input)


    return new{X=input,Y=3};


    Doesnt quite look right, though. I think I’d rather use the generic syntax than the above syntax.

  2. Gabe says:

    C++ already has a concept called "auto" which nobody uses, and it specifically refers to a local (stack-allocated) variable. Since "auto int i;" is the same as "int i;", they could say that if you leave out the type name, you could make sure the "auto" is always there and infer the type if need be. The only question is if you can have a "static auto", as "auto" right now is the opposite of "static".

    Since C# doesn’t have an "auto" just waiting to be used, I do like "var". However, I definitely like "let" even more — with the added bonus of looking a bit more like functional languages. Unfortunately that won’t work when they get around to allowing infered method return types. "private let SomeMethod(int i)" looks pretty stupid. For that case, though, I prefer "auto" because it implies "automatic".

  3. duncan says:

    I’m a fan of the word ‘infer’ inplace of ‘var’, sure it’s a couple of extra chars but it is very explicit.

    Otherwise though I really really really want to start using this in my everyday work!

  4. damien morton says:

    static var Foo<S>(S input)


    var y = 3;

    return new{X=input,Y=y};


    static let Foo<S>(S input)


    let y = 3;

    return new{X=input,Y=y};


    static auto Foo<S>(S input)


    auto y = 3;

    return new{X=input,Y=y};


    static infer Foo<S>(S input)


    infer y = 3;

    return new{X=input,Y=y};


    Hmm, Im leaning towards var. It just seems to work better in both cases.

  5. RonO says:


    The term ‘var’ has nothing to do with VB. ‘var’ is defined in JavaScript/JScript as a universal (and dynamic) type.


    I think ‘infer’ is a much better term. I’d accept ‘auto’, but if it doesn’t mean the same thing in C++, it might cause some confusion. Whatever the new term, I’d like to see ‘var’ dumped for this context.

  6. Nick says:

    I think var is a very unfortunate name because of the Javascript usage… and since a lot of C# people do ASP.NET and therefore do Javascript also, its bound to lead to confusion.

    Frankly however, I’m quite surprised to see this feature appear at all, mostly because it makes code less readable in many ways then code with explicitly set variables. From the outset my understanding was that C# as a language designed to be very readable, and force the programmer to use constructs that may not be normally needed just to make code easier to read (like override on virtual methods in inherited classes). This whole concept seems to go against that idium.

    This feature basically requires you to make heavy use of intellisense in order to review and understand someone else’s code, because types are easily visible. I actually still print out code on paper when I review it (shocking I know), and this "feature" would make that 10 times more difficult.

    I just have this feeling that overall, it will make for sloppy code. As things have progressed, people have less and less understanding of what Visual Studio is doing for them under the hood… and I’d hate to see something as basic as type declaration be another one.

    Call me old fashioned.

  7. CoryC says:

    Instead of "infer" how about "imp"?

    infer seems too long to type all the time. let is just "too BASIC", I think you’ll get push back from that.

    Plus, "imp" is an abbreviation (err… of sorts) for "Implicitly Typed Local Variables".

  8. I don’t care much what you call it. Although I agree that "var" is probably not the best name, I think people will get used to it quickly. "auto" would probably be my first choice, especially as that’s what C++ is using; it helps make knowledge transferable between languages (where var actively impedes that by meaning two different things in the languages it appears in).

    What I *do* think though is that it’s important to make anonymous types "nonymizable", that is, first-class structural/record types. The more I think about this the more I think it needs to happen. Otherwise what do you do if you have code that uses an anonymous type and you do "extract method" refactoring on it? You can end up with situations where there’s code you simply can’t extract because there’s no type you can use to pass the objects across the method call boundary.

    I’m not averse to supporting inference of method return types from "return" statements in the body (in fact I think that’s a good idea), but that doesn’t help with the parameter types.

    So IMHO (who am I kidding with the "humble"? 😉 ) you guys (the C# team) should be working with the CLR team to get true structural record types into the CLR itself. These types would have to live either outside all assemblies or in some "magic" assembly that can get types added on the fly (lightweight typegen? please? pretty please?) and then the C# anonymous type behavior can be expressed in those terms and work right across method call and assembly boundaries. Syntax for actually referring to those types is trivial once the infrastructure is in place.

    Another benefit of doing that is that people who *don’t* like automatic inference aren’t shut out of using anonymous types altogether – they can still use Linq and projection and so on, they just have to type more.

  9. Daniel Graham says:

    I agree that the name should be changed from var to something like infer. I would actually prefer to have the same keyword as the C++ compiler. Also ‘var’ is already used in JavaScript, but much differently, so it seems that the name ‘var’ is something that should be avoided if possible (IMHO).

  10. Kevin Dente says:

    On Stuart’s point, by using anonymous types we’re basically creating a type that can’t be used outside the current scope (ie can’t be passed to another method) right? Won’t that result in horribly long and impossible to understand methods that can’t be decomposed into helper methods? Seems like a major maintainability issue.

  11. dhchait says:

    +1 for "infer"

    next best choice would be "auto".

    ps. RonO – I believe Damien’s comment on VB-ish referred to using "let" rather than to "var".

  12. Sean Chase says:

    My vote is to leave it at "var". I like it. Otherwise my second choice would be "infer". var looks fine to me though, not sure what the hype is all about.

    Cool post. Please discuss some cool use of lambdas! 🙂

  13. damien morton says:

    infer x = 5;

    What does that mean? It reads like you are telling the compiler to infer that x is 5, when in reality you are telling the compiler to infer the type of x from the assignment of 5 to it.

    It might be kinda cool to be able to say something like this:

    infer<T> x = 5;


    var<T> x = 5;

    and then you can use the actual type, T, which is inferred, at other locations. Its a bit awkward because its not the usual generic declaration semantics, and its a lot more awkward to type than simply ‘var’.

    Even better might be to say something like this:

    <T> x = 5;

    Still has that awkward-to-type element to it.

    Daniel – actually, I dont know VB well enough – I thought ‘var’ was in VB, but its actually ‘Variant’ which is the problem.

    I dont think we need to be tiptoeing around usage in other languages. ‘var’ in javascript is used to declare variables. Fine. ‘var’ in C# is used to do the same, but also to infer the type. If theres any confusion, its going to be momentary.

  14. Robert Kozak says:

    infer as a key word sounds like it would be perfect (and I like it alot) but on the other hand it really doesn’t read well as Damien states.

    infer x = 5;

    X is a 5

    imp as Cory says is a nice keyword to but I would spell it out as imply.

    imply x = 5

    which, of course, reads as "Imply X as 5" which still doesn’t really explictly imply type.

    Auto is out as it can cause confusion.

    typed is another consideration.

    typed x = 5

    but it makes it sound like x is typed but typed from what?

    implytype or infertype will combine everything in one keyword and make it more readable.

    implytype x = 5;

    infertype x = 5;

    These are just suggestions and not necessarily the best. I just thought I would throw it out there for discussion.

  15. CyrusN says:

    Stuart/Damien: Making anonymous (structural) types first class citizens is somethign that is being investigated. For the PDC there simply wasn’t any time to do anything that exstensive. If you noticed, all the features that we did demonstrate exist *entirely* within the langauge level and only depend on .Net 2.0 features. This lack of dependence allowed ust o be very nimble and to produce a preview that people could play around with and which we could use to experiment with.

    We’ll let you know if/when anything changes regarding this. And i’ll definitely go deeper on this on a post regarding Anonymous types.

  16. Cyrus, thanks for the info 🙂

    I had actually noticed that most of the C#3 features were purely language level – I hadn’t quite made the leap to notice that they were *all* that way and ran entirely on the unmodified 2.0 platform though.

    I’d certainly noticed that 1.x->2.x was a huge CLR change to support generics, the so-far-announced 3.x features at the CLR level were underwhelming. That’s not entirely a bad thing – it’s a testament to the power and maturity of the platform. But there are still areas that the CLR could use improvement in.

    It raises an interesting question: I’d assumed that just like 2.0, C# 3.0 would be released in parallel with the .NET framework 3.0 and a new major revision of the CLR. But I realize now that I don’t think I’ve ever seen that formalized anywhere. Do you know if that’s actually been announced yet, one way or the other?

    It’s certainly impressive to see how far it’s possible to push the language with no CLR help, but just like with Nullable, I think there are aspects of this work that would suffer if they ended up enshrined in their current form, because it would prevent doing them "right" in the future. Anonymous types versus first-class structural types is the biggie here.

  17. loc says:

    All right, so both the problem and the reward are code readability/repetitiion.

    Why not add a feature in Intellisense that can convert:

    var i = 5;

    var s = "Hello";

    var d = 1.0;

    var numbers = new int[] {1, 2, 3};

    var orders = new Dictionary<int,Order>();


    int i = 5;

    string s = "Hello";

    double d = 1.0;

    int[] numbers = new int[] {1, 2, 3};

    Dictionary<int,Order> orders = new Dictionary<int,Order>();


    That would solve everything for the coders, just by clicking on a button to convert the code. Tell me why this resolution would cause potential problems. I’d like to hear from you.

  18. CyrusN says:

    Loc: I talked about exactly that in my original post. Specifically:

    "And, because this seems like a feature with it’s own plusses/minuses, and because it seems like people will want to move back and forth between implicit/explicit types depending on the code they’re writing, it will make a lot of sense for us to provide user tools for this space. Some sort of refactoring like "Reify variables". Or… since people won’t know what the heck that means: "make variable implicit/explicit.""

  19. CyrusN says:

    Grrr… not getting notifications about all these posts. Very frustrating.

  20. loc says:

    Yeah, that’d be nice if Intellisense could convert var to explicit type back and forth. Then I’ll have no problem with code clarity.

    Also, you know if you type " this.", Intellisense would then display the list of class’ properties and methods. How about we can type " ." (<space><dot>) and have Intellisense display the local variables? That’d be a convenient plus, or so I think.

  21. CyrusN says:

    Stuart: The runtime team has a whole bunch of priorities that are extremely important to them. SPecifically: Stability, Scalability and Security (as well as many more). Introducing a new type concept into the CLR is a *huge* amount of work. It’s potenttially destabilizing, and if it opens up a type hole, then you cna have security problems.

    So trying to get runtime support for things is something you think very carefully about.

    That said, we’re always evaluating if it would make more sense for somethign to be done at the CLR level and if we hsould go down that route. However, it’s a great exercise to try to see what is possible when you do things entirely at the language level.

  22. loc says:

    Uh oh, sorry for getting too excited before finishing reading the whole post. Besides, I’m at work, so no time to read carefully. =)

    Yeah, having "var" would be nice after all.

  23. CyrusN says:

    Loc: I’m forwarding your suggestion to Karen (who’d in charge of how intellisense will work in Orcas). We’re going to be thinking a lot about new ways we can show you information.

    If you have other suggestions that you’d like to see, then go to and submit it there. THat way it will get reviewed by the team and can get voted on by the community. It’s too late for it to be ocnsidered for Whidbey, but they will all be considered for Orcas.

  24. loc says:

    To be more specific, how about we just type:

    var orders = new Dictionary<int,Order>();

    and when you hit "Enter" for a new line, it automatically converts to:

    Dictionary<int,Order> orders = new Dictionary<int,Order>();

    Someone (I, for one) might prefer that way over having to double-click on the "private void DoSomething()" line to convert "var" <==> explicit type.

    (and to make a suggestion on that web page, you have to sign in? hmmm.)

  25. CyrusN says:

    Loc: Yup. You have to sign in. That was to prevent the spam assault we were getting when sign in wasn’t required.

  26. Cyrus, I completely appreciate that the runtime team have to focus on stability and security and scalability and all that good stuff. I’d never dream of suggesting they should stop focusing on those things – it would be disastrous if they did.

    Having said that, Orcas is still quite some way away at this point and so there’s no better time than now to be thinking about the big runtime-level changes. While the Nullable situation turned out okay in the end, I have a funny feeling nobody in the C# or CLR teams would like to repeat that with some new concept in Orcas that turns out at the last minute to be unacceptably limited at the pure-language level.

    I think that structural types are such a concept. In fact I think in Orcas+1 (does that have a name yet?) it would be nice to even get them CLS-compatible – I bet there are a whole bunch of languages that would like to be able to play happily together with record types.

    The other suggestion I think I already made to you which might take runtime support is

    Foo<T> {

    T? val;


    which would translate to "T val" when T is a reference type or Nullable<>, but "Nullable<T> val" when T is a value type other than Nullable<>. I don’t think that can be expressed in today’s IL so that would need runtime support too. Probably less than structural types would, I guess. But still.

  27. Patrick Lioi says:

    I agree that ‘infer’ should be the new keyword.

  28. loc says:

    Personally, I think "infer" is a verb (although you can say it’s short for the noun), so it shouldn’t be a name.

    How about just anonymous ("anon" keyword)? Or better yet, "loc" keyword? Just kidding.

    I’m ok with var.

  29. CyrusN says:

    Loc: "anonymous" would be a pretty poor name 🙂

    anonymous means: Nameless

    However, these variables are definitely *not* nameless. They have names, just not types 🙂

    So i think i’ll definitely be ‘axing’ the "anonymous" keyword right now 🙂

  30. Chris Nahr says:

    How about… dim? HAR! Sorry.

    Seriously, my first preference would be for "auto" since it’s the same as in C++ and implies that the type is determined AUTOmatically.

    My second choice would be "let" since that’s the keyword used by ML/OcaML/F# which invented the concept of implied typing AFAIK.

    "infer" reads a bit strangely since C# is inferring the type, not the variable or its value. "var" would actually be an okay choice if it wasn’t already used by JavaScript and reminiscent of VB/COM variant types. But since it is… I agree that it’s not a good choice.

  31. damien morton says:

    ‘let’ only works if you dont use it for method declarations.

    public let Foo(int x)



    but it works fine if you can infer generic types from return values, and ditch the use of ‘let’ for return types:

    public T Foo<T>(int x)


    let z = new{X=x,Y="bleh"};

    return z;


    Anyway – it hard to know what th ebest word is without knowing how its going to be used in the rest of the system.

  32. loc says:

    I meant "anon" as "anonymous type" and not "anonymous variable".

    anon orders = new Dictionary<int,Order>();

    The variable name is "orders", and the type name is anonymous – or no type. According to


    1. Having an unknown or unacknowledged name: an anonymous author.

    2. Having an unknown or withheld authorship or agency: an anonymous letter; an anonymous phone call.

    3. Having no distinctive character or recognition factor: “a very great, almost anonymous center of people who just want peace” (Alan Paton).


    How about "anytype" keyword? Or just "any"?

  33. damien morton says:

    Why not simply do without ‘var’ or ‘let’ or ‘infer’, and make type declarations optional.

    I mean, a non-declaration, like ‘var’ really doesnt tell us much at all.

  34. loc says:

    Damien, I’ve thought about that, but then you don’t know where it’s declared and its scope (like is it a global or local var?). It’s confusing, at least to me.

  35. damien morton says:

    loc: theres plenty of precedence for optional type declarations, or at least the absence of them.

    In Pyhton, Javascript, Perl, Ruby, Haskell – you dont need to declare your types at all. people use these languages in production environments and dont get confused.

  36. loc says:

    Python, Perl/Ruby, and Javascript have dynamic typing, don’t they? If those languages were so great, C#/C++/Java would have been much less popular I think. 🙂

  37. CyrusN says:

    Damien: "Why not simply do without ‘var’ or ‘let’ or ‘infer’, and make type declarations optional.

    I mean, a non-declaration, like ‘var’ really doesnt tell us much at all. "

    Sure it does. It tells you that you’re declaring a variable, as opposed to just using it.

  38. damien morton says:

    loc: those languages are great and they have captured a lot of mindshare. The existance of those langauges is why we are having this dicsussions about ‘var’. And populariy be damned. Haskell is probably the most obscure language that is inspiring many of these changes.

    loc: python, perl, ruby and javascript dont require type declarations. haskell infers types, much like C# is planning to do. None of them require variables to be ‘declared’, though javascript allows for it.

    I dont know about the other languages, but Python has a type-inference system in the form of a specialising compiler called psycho. Once you introduce type inference and generics (cf specialising compilers), the boundaries between the world of statically typed languages and dynamically typed langauges gets somewhat fuzzy.

    cyrus: Let me be a little nitpicky about this:

    ‘var’ tell us that this is the first use of a variable and that its type is being inferred at this point.

    Since other languages manage just fine without such a declaration, why does c# need it?

  39. JC says:

    I wonder how the C# team will report errors on an anonymous type. Are we going to get the same huge errors you get when compiling C++ template code?

  40. CyrusN says:

    JC: "I wonder how the C# team will report errors on an anonymous type. Are we going to get the same huge errors you get when compiling C++ template code? "

    Why don’t you try out the alpha and see? If you don’t like the errors, let us know so that we can work on it and make it better.

  41. CyrusN says:

    Damien: "Since other languages manage just fine without such a declaration, why does c# need it? "

    Well, to be nitpicky in return:

    a) a lot of the feedback we get from users is that they do *not* like languages that eschew declarations.

    b) There are many different mindsets about this, however our current user base seems to prefer the more staticy declaration-oriented style of programming.

    c) technically c# doesn’t *need* anything. It’s turing complete and you could always implement *every* single feature in a roundabout manner. But that would be silly 🙂 Language design is about striking a proper balance between many things and so far we like the balance that "var" gives us.

  42. andersonimes says:

    I see where you are going with the reason for ‘var’ being due to the new Linq features of C# 3.0. I see that it would make things much easier there. I do, however, think that its use outside of this construct will make things much more ambiguous.

    Your ‘lollerskates’ example, in particular, scares me quite a bit. In these cases I would be vehemently against letting my programmers use this feature.

    In particular, I worry about those cases where a programmer is being returned a different type than he/she originally anticipated and is using common method names that will still compile. Example (not that you would do this, but consider anyway):

    public StringBuilder GetParagraph(){}

    var paragraph = GetParagraph();

    textbox1.Text = paragraph.ToString();

    Now consider the definition of GetParagraph changes:

    public MyCustomTypeWithToStringNotOverriden GetParagraph(){}

    You’ll see here you will get object.ToString() instead of StringBuilder.ToString(). No compilation warnings. This, to me, it the advantage of a strongly typed language. I realize that ‘var’ does not REALLY change the strong-typedness of C#, but it removes one of those compiler errors that would tell a programmer to look something over and make sure it is still correct.

    That’s just my 2 cents. Great article! It’s great to see what you guys are working on as you go through the design process.

  43. Cyrus,

    Always good to see you…

    Using "auto" or "infer" wouldn’t be so bad. There is a suggestion on the Product Feedback site to use "let", but I disagree with that, since the implication is something other than what is actually going on.

    I think var is ok, as are the other recommendations you have. However, I think that var is better only because it is shorter, and you will run less of a risk of conflicts with current code (because you are introducing a new keyword, you have this problem).

    BTW, you state:

    s.FoobyBoob(); //This won’t compile. string doesn’t have ‘FoobyBoob’ method

    As I am sure you know, with extension methods, it could. =)

  44. John Rusk says:

    Instead of "var" or "infer" what about "local"?


    local x = 5;

    It’s reasonably short (but not as short as var admittedly), and has the advantage of corresponding to the official name of "Implicitly Typed Local Variables".

  45. Ryan Milligan says:

    My first thought on seeing the "var" keyword was that I would actually rather have the compiler able to infer the *other* side of an assignment. To use your own example:

    Dictionary<IOptional<IList<string>>,IEnumerable<ICollection<int>>> characterClasses = new();

    Visual Basic has been able to do this for years with their "Dim x As New X()" syntax, and it has the advantage of only removing truly redundant text. Obviously, you still need the "var" keyword for anonymous classes and places where a method returns some truly onerous and hard-to-understand type (if I had a function that returned that particular kind of dictionary in real life, I’d probably actually use "var" for the variable), but I think it removes an awful lot of duplication with basically no cost in terms of readability because the type is always statically declared somewhere in the statement.

    Partial inference also might be interesting. What if you could type the above type as:

    Dictionary<var, var> characterClasses = …;

    No "real" advantages to this from a syntax perspective, but I think it enhances readability significantly. You still save yourself a lot of typing, but at least you can glance at it and quickly know as much as you need to know about the type of the variable.

    All in all, though, as long as the C# 3.0 language service allows me to hover over a var-typed variable and see the actual infered type in a tooltip, I think I’ll be satisfied with the readability.

  46. loc says:

    ryan, if you search for "*meh*" and read from there, you’ll see that "var" was meant for the linq stuff that’s coming in C# 3.0. Basically, if you can’t express anonymous type, then declaring this following variable is pretty cumbersome:

    var q =

    from c in customers

    where c.City == "Seattle"

    select new {


    Orders =

    from o in c.Orders

    where o.Cost > 1000

    select new { o.Cost, o.Date }


  47. Ryan Milligan says:

    Oh, I’m aware of that — hence the phrase "Obviously, you still need the ‘var’ keyword for anonymous classes" in my previous post. I wasn’t suggesting replacing the current ‘var’ functionality, just some extra functionality that I think would be interesting on top of it and would improve overall code readability.

  48. Brian Stock says:

    "To be more specific, how about we just type:

    var orders = new Dictionary<int,Order>();

    and when you hit "Enter" for a new line, it automatically converts to:

    Dictionary<int,Order> orders = new Dictionary<int,Order>();"

    This potentially removes some of the functionality though. E.G.

    public Order someMethod()



    var orders = someMethod();

    Now, if that’s just changed automatically to Order orders = someMethod() what happens when I change the return type of someMethod? Does it throw an error? Does it dynamically change the type? Something I might like to see is for it to stay var and when you mouseover it displays the inferred type.

  49. loc says:

    Brian, what if we don’t need that functionality? what if we want to throw an error? Anderson (search for andersonimes to read his response) gave an example where throwing an error/warning is desirable when you change the return type of "someMethod".

    What you might like to see is classic Intellisense though. 🙂

  50. Brian Stock says:

    Well, yes, it’s possible that we don’t need that functionality, but I think it’s kind of nice. I also realize that tooltips display information about methods et cetera, I just want to make sure that it does this to the var keyword itself. Doesn’t really help those printing, but it sounds like there’s going to be functionality to Reify so that takes care of that. I guess I’m just not convinced that var would cause that much confusion if those two things are in place.

    Actually, I did overlook Anderson’s post and yes, that could cause some problems. Maybe you’re right and it should just automatically change var to the appropriate type.

  51. Based on the misconception I’ve had to deal with *every* time I’ve explained this to someone so far, I humbly suggest:

    notvariant x = 42;


    Since I’ve always quite liked Magritte, it did occur to me to suggest:

    cecinestpasunvariant s = "Foo";

    but that’s might cause confusion. And I admit it’s not terribly concise.

  52. As an alternative for the "var" keyword, I think "set" is also a fine choice.



  53. loc says:

    What else is going on, Cyrus? Update…

    4th quarter is keeping everyone busy. I still haven’t looked for PDC articles/webcasts to enjoy…

  54. Chris Martinez says:

    I guess I’m a little late in the game, but I have been waiting for this blog since the PDC. Unfortunately, after a few days of searching post-conference, I stopped trying to look. I’m relieved to see that people are talking about this.

    Please excuse me if a duplicate anything from another posting because there is quite a bit to read.

    I think Cyrus hit it right on the nose with regard to the "var" keyword and using a substitute. While at the PDC I had very brief chance to speak with Anders Hejlsberg and the first first thing I commented to him on was why was the "var" keyword used instead of something like more straight-forward such "infer" (which is still very short).

    One of the things I noticed reading some of the other postings is how the "var" keyword is used. It can ONLY be used within the local scope of a function (obviously including properties, which are really specially treated functions anyway). With that said, you can’t have a method like "public var Foo()" or something like "public void Foo( var x )".

    When I was reviewing a Visual Basic demo using type inference, it became very clear why the "var" keyword is needed at all in C#. Obviously, since C# variables are declare as "{Type} {Name}" there must be a placeholder for "Type". Anyone who is familiar with Visual Basic should know that this not a problem because variables are declared as "Dim {Name} As {Type}". Therefore "Dim x = 5" implements type inference with no change to the language (other than "x" is inferred instead of being typed as System.Object), whereas this is not the case in C#.

    My support of the "infer" keyword comes from the natural English-like reading of code. For example, in my words:

    "Dim x = 5" says "Declare ‘x’ and infer its type from ‘5’".

    In my option "var x = 5" does not say the same thing in English readable terms, but I believe "infer x = 5" does.

    When I spoke with Anders he also mentioned that there had been a lot of debate over the keyword to be used and spouted off a few such as "auto". I think it is exceptionally important to come to an agreement of what the keyword should be since it is not yet set in stone.

    "var" (or whatever it will be called) is a new keyword to the language so there isn’t really anything to compare it to. However, if you consider the language changes made from C++ to C# there are other examples. In C++ assembly scope was declare using the "friend" keyword, which was terrible. This was appropriately named "internal" in C#, which makes far more sense. Therefore, I think it is important the C# 3.0 team doesn’t allow another abstract and confusing keyword to be added to the language.

    While I personally really like "infer", other alternatives such as "let" could also work. As mentioned by a few other people, I don’t think "auto" should be used because of it’s meaning in C/C++ even though it is usually never used. While it may not confuse new C# developers, it will certainly throw veteran C/C++ developers moving to C# for a loop.

    Beyond a few little quirks, which of course there is plenty of time to work out, I think Microsoft has done a terrific job in continuing to be truly innovative. I may be reaching here, but I think the concepts taken from Cw, and placed into C# 3.0 and the other languages, are likely to be at least as innovative as C++ or Java when they first emerged. Keep up the great work!

  55. Dan says:

    Heres the main reason I wouldnt like to skip the "var" keyword altogether:

    int ill = 5;

    ili += 5;

    Debug.Assert(ill == 10); // Fails

    Did you spot the bug on a single read-through? And even if you did, would you be able to spot the bug at all when you write it yourself (and expect to have not written a bug), especially if you have 20 lines of code in that function?

    With "var" you would get a compiler error.

    Id prefer "var" or "infer", var is short and to the point. I dont like "set", just try talking about it, "the select function returns a set" (a set variable, or an ISet set?).

  56. IM says:

    The keyword should clearly be "???". E.g:

    void DoSomething()


    ??? x = GetSomething();


    So, the nullable version of same would be:

    ???? x = GetSomething(); //nullable

  57. David Conrad says:

    Cyrus – what does it mean that this is the start of a series of posts on C# 3.0 features? You don’t seem to have ever covered it again.

    Pros and cons of the names:

    var – Pro: simple, short, to the point, appears to be the choice already anyway; Con: will be confused with VB variant and JavaScript var.

    let – Pro: makes the ocaml hacker in me smile, simple, short, to the point; Con: would be confused with BASIC let statement.

    infer – Pro: clarifies that it’s type inferencing, not typelessness or variant types (I really liked this idea for a second); Con: as someone pointed out, it’s a verb, so it implies that you are telling the compiler to do type inferencing, and thus that the compiler only does type inferencing when you explicitly tell it to, but I believe you are, or are planning to, do it in other cases.

    imply, anon, auto, loc – Pro: I can’t think of any; Con: yuck, blech, Ack! Pffft!

    ??? – Pro: too funny; Con: too funny.

    x = w? x ?? y : ???? z = from …

  58. Wolf Logan says:

    haven’t heard anyone suggest "new" yet —

    new foo = new Bar();

    new result =

       from item in someCollection

       where item.value == 2

       select new {, };

    syntactically unambiguous, acts as a good marker for variable declaration v. usage (this variable is "new" at this point in this context), and is three letters long 😉

    as regards the "var" confusion between C#3 and JavaScript: I think we’ve already torched that bridge — there’s already extensive confusion between C#3’s "from", "where", and "select" and the similar-sounding (but functionally entirely different) keywords in SQL. I have my own opinions about that, but the fact remains that we’re already borrowing words from other languages, and we have to live with the level of confusion that will cause.

Comments are closed.

Skip to main content