Hacker News new | past | comments | ask | show | jobs | submit login

"var" is a shorthand to not declare the type when it can be inferred, in most cases to avoid Foo foo = new Foo(). The point is that it avoid repetitive typing, while still preserving type safety and everything that comes with it: compiler checking that right types are used in the right places.

[Digression While it is possible to use in var foo = GetIt() the practice is discouraged because it makes the type of "foo" opaque to the casual reader]

For a parameter definition, its use clearly makes no sense. What is the type for the following method?

void Demo (var x) {}

"var" in the above example would not really add much value, neither would the following example, where inference will oscillate from useless to fragile, depending on who you ask:

void Demo (var x) { var j = x.Parent; }

For method return types the reason is simple, it serves no useful purpose, in fact, it can be quite damaging as the public API contract can change during routine work. Consider a method:

var Demo (PointF f) { if (f.X < 0) return f.X; return 1; }

The above method signature cal oscillate easily between float or double on the day that someone changes the 1 with 1.2. Reading a diff or a patch file wont catch the fact that you have accidentally changed the type of the function.

If this is the kind of code that you need to write (both cases above), then by all means, use the right tool and replace "var" with "dynamic". I would argue that using "dynamic" for the sake of not declaring the type there is a poor practice, but I am not about to lecture you on poor coding choices.

Generic type paramters: your comment makes no sense.

Lamdba expressions: makes no sense, the parameters are already inferred. Not sure what value (var x) adds over the already existing (x) syntax.

Which brings us to the very case I quoted "field declarations".

The ones that you skipped where it is supported: local variable declarations, for statements, using statements, consts locals and fixed statements.




Honest question: Are you just playing devil's advocate? It appears that the reasoning for C#'s design is that it targets LINQ as a goal, and the new features (like var and extension methods) were implemented just for the LINQ case, not considering those features by themselves.

In fact, the lack of type inference for fields was said to be due to technical limitations in the C# compiler implementation, not for any language reason. [1] Sure, any product will have limitations due to schedules/resources, but that doesn't change the fact that they're unfortunate limitations that could be fixed. C# hasn't addresses these issues, but they've had 2 or 3 releases since they were introduced.

>For a parameter definition, its use clearly makes no sense. What is the type for the following method? >void Demo (var x) {}

In that case, x has no constraints (it's unused), so it's generic. Pretty simple. An unused parameter isn't that useful outside of a few cases. Usually you'll use the variable, and constraints can be inferred. Or you'll find a constraint that limits the type to a concrete type. Here's some examples:

  void dub (var x) { Tuple.Create(x,x); } // x is T
  void uri (var x) { new Uri(x); } // x is string
  void cmp (var x, var y) { Nullable.Compare(x, y); } // x and y are Nullable<T> where T : struct
The example of "void Demo (var x) { var j = x.Parent; }" is probably one place you'd want it to fail, because using member access to infer types can get complicated, at least within C#'s type system. You'd want a static duck typing system in this case like "anonymous interfaces" or something to that effect.

Arguing against return type inference is wierd: C# does that in anonymous functions - certainly you don't think we should have to annotate types there!

As for type signatures changing, if you need want to keep public contracts, then write them out! No one is saying you need to always infer everywhere, just that it's a great aid. Also, this particular example just demonstrates why C#'s type coercion is a bad idea, albeit understandable, given their desire to follow C style.

Generic type parameters. What do you mean it makes no sense? I can't write, e.g. "new List() { 1 }" - it complains List needs a type parameter. Another example: "Func<var> = () => 1". Nope, I'm required to explicitly provide the type. What if C# didn't have syntax support for Nullable<T>? You'd have to do e.g. "x = new Nullable<int>(1)" or create a helper function like Tuple and have e.g. "x = Nullable.Create(1)". Generic type parameter inference only happens on methods.

Also note that C# can't infer generic type parameter constraints - you've got to annotate them all by hand. Makes sense, I guess, because it doesn't infer any generic type parameter definitions, either.

Lambda expressions can't be type inferred. "var x = () => 1" does not work (CS0815). This is because of the same syntax for expression trees versus anonymous functions. And if that was changed, you'd still need to "promote" func somehow, due to C#'s wierd nominal typing for delegates.

Fixed statements can't be type inferred either: error CS0821: Implicitly-typed local variables cannot be fixed.

The things you mentioned, for (and foreach), using -- those are all local variable declarations. So we have it working for local variables, for some generic type parameters, lambda parameter definitions (when the lambda type is known) and lambda return types.

It's a nice start, and it makes C# far more enjoyable than some other languages like Java. But it's still quite limited, without solid reasons.

1: http://blogs.msdn.com/b/ericlippert/archive/2009/01/26/why-n...




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: