16

Possible Duplicate:
Using var outside of a method

class A {
string X;
}
// Proper
class A {
var X;
}
// Improper (gives error)

Why is it, that i cant have var type variable declare in Class and what can be done in order to achieve it OR what is an alternative ?

In function/method, i can declare a var type variable,then why can't, i do it in class ?

Thanks.

Community
  • 1
  • 1
Pratik
  • 11,534
  • 22
  • 69
  • 99
  • 1
    In function/method, i can declare a var type variable,then why can't, i do it in class ? – Pratik Dec 21 '10 at 06:14
  • 1
    There is no need to do this; if you were able to it would just make the type of the variable less explicit, hence your code more obscure. Perhaps you are misunderstanding the purpose of the var keyword. – Kirk Broadhurst Dec 21 '10 at 06:31
  • Needless, annoying duplication when declaring class members: Dictionary D = new Dictionary(); – kaalus Mar 26 '20 at 20:29

8 Answers8

21
// method variable
var X;

is never valid - even inside a method; you need immediate initialization to infer the type:

// method variable
var X = "abc"; // now a string

As for why this isn't available for fields with a field-initializer: simply, the spec says so. Now why the spec says so is another debate... I could check the annotated spec, but my suspicion would be simply that they are more necessary for method variables, where the logic is more complex (re LINQ etc). Also, they are often used with anonymous types (that being the necessity for their existence); but anonymous types can't be exposed on a public api... so you could have the very confusing:

private var foo = new { x = 123, y = "abc"}; // valid
public var bar = new { x = 123, y = "abc"}; // invalid

So all in all I'm happy with the current logic.

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
6

If you really don't know the type of object your instance variable will hold, use object, not var. var doesn't mean "i don't know", it means "infer the type for me" - this is why it can never be used on class members.

Bradley Smith
  • 13,353
  • 4
  • 44
  • 57
  • but when i type in function/method i can declare a var type variable – Pratik Dec 21 '10 at 06:13
  • 1
    @Rahul It works at method scope because the variable lives and dies within the block, therefore the compiler can easily infer its type. At class scope, the compiler would have to consider state, sequence, instances and all sorts of other factors. – Bradley Smith Dec 21 '10 at 06:14
  • Well Thanks. Can you suggest me some differences & similarities in object & var from which i can decide whether or not i can use object type in my code. – Pratik Dec 21 '10 at 06:19
  • @Rahul, see [this question](http://stackoverflow.com/questions/1552881/difference-between-var-and-object-in-c) about `var` and `object`. – Matthew Flaschen Dec 21 '10 at 06:22
  • 2
    As Marc said, this doesn't really explain why it doesn't infer it when there *is* a field-initializer. – Matthew Flaschen Dec 21 '10 at 06:28
4

Because C# doesn't support this level of type inferencing. Your alternatives are to use a language, such as F#, that does support this level of type inferencing or beg the C# team to implement the feature. I've got a pretty good guess which one you'll have more luck with...

James Kovacs
  • 11,549
  • 40
  • 44
  • using F# in not relevant for me neither is begging C# team.Looking forward for anything different than these two! – Pratik Dec 21 '10 at 06:17
  • 5
    The reality is that C# doesn't support this feature. My point wasn't to switch languages, just that support is possible (e.g. F#) and the C# team chose not to implement "var" for anything other than local variables. Begging the C# team was me being tongue-in-cheek. – James Kovacs Dec 21 '10 at 06:19
3

var in C# is a implicitly typed local variable used to infer the type from the RHS of the given expression, which needs to be resolved at compile time. When you declare a var with no RHS value in the class definition, there is no way for the compiler to know the type that you are trying to assign to var.

C# doesn't support implicit typing for class variables.

jatin
  • 1,379
  • 8
  • 7
0

Because the actual type of a var is inferred from the context in which it is used. For fields (class member variables), there is no such context.

gstercken
  • 3,223
  • 3
  • 20
  • 15
0

You can argue that the intent is quite obvious if you would write var _users = new List<User>() as a field declaration.

The problem is that not all field declarations contains an assignment which is required to infer the type. (You might want to initialize a field through the constructor)

Mixing both var and normal type declarations would look like a nasty soup. Therefore it's not possible.

(at least that's my guess)

jgauffin
  • 99,844
  • 45
  • 235
  • 372
0

Yes, the var keyword is only allowed for local variables.

It was introduced in the language to be able to handle an anonymous type, that only exists in a local scope. As the anonymous type is limited to the local scope, it makes sense to only allow the var keyword in a local scope.

Additionally, it never works to use the var keyword without specifying a value, as that is used to infer the data type:

var x = "asdf"; // works

var x; // doesn't work

The normal way of declaring a variable is using a specific data type. Use the var keyword when you can't specify a data type (e.g. when the type is anonymjous) or when the type is superflous (e.g. repeated literally in the value). Example:

var x = new { Key = 42, Name = "asdf" };

var y = new System.Text.StringBuilder();
Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • 2
    Why the downvote? If you don't explain what it is that you think is wrong, it can't improve the answer. – Guffa Dec 21 '10 at 07:27
0

It is all because of the Build order. You can declare var in only methods. Compiler builds everything but methods first and thats why the type of the object will be clear to the compiler if you use it inside of a method. Jon had a great answer about this but can't seem to find.

Pabuc
  • 5,528
  • 7
  • 37
  • 52