在与同事讨论了c# 3中var关键字的使用后,我想知道人们对通过var适当使用类型推断的看法是什么?
例如,我很懒地在有问题的情况下使用var,例如:-
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.
var更合法的用法如下:-
var l = new List<string>(); // Obvious what l will be.
var s = new SomeClass(); // Obvious what s will be.
有趣的是,LINQ似乎是一个灰色区域,例如:-
var results = from r in dataContext.SomeTable
select r; // Not *entirely clear* what results will be here.
结果很明显,因为它将是一个实现IEnumerable的类型,但它并不完全明显,与var声明一个新对象的方式相同。
当涉及到对象的LINQ时,情况就更糟了,例如:-
var results = from item in someList
where item != 3
select item;
这并不比等价的foreach(var item in someList){//…}相当于。
这里有一个关于类型安全的真正问题——例如,如果我们将该查询的结果放在一个接受IEnumerable<int>和IEnumerable<double>的重载方法中,调用者可能会无意中传入错误的类型。
Var确实保持强类型,但问题是,在定义中不立即显示类型是否危险,当重载意味着当你无意中将错误的类型传递给方法时,编译器可能不会发出错误,这种情况会被放大。
你最可能需要它的时候是匿名类型(100%需要);但它也避免了琐碎案件的重复,IMO使界限更加清晰。对于简单的初始化,我不需要看到类型两次。
例如:
Dictionary<string, List<SomeComplexType<int>>> data = new Dictionary<string, List<SomeComplexType<int>>>();
(请不要编辑上面的hscroll -它有点证明了这一点!!)
vs:
var data = new Dictionary<string, List<SomeComplexType<int>>>();
然而,在某些情况下,这是一种误导,并可能导致错误。如果原始变量和初始化类型不相同,请谨慎使用var。例如:
static void DoSomething(IFoo foo) {Console.WriteLine("working happily") }
static void DoSomething(Foo foo) {Console.WriteLine("formatting hard disk...");}
// this working code...
IFoo oldCode = new Foo();
DoSomething(oldCode);
// ...is **very** different to this code
var newCode = new Foo();
DoSomething(newCode);
来自c#团队的高级软件设计工程师Eric Lippert:
为什么引入var关键字?
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.
我特别强调。整篇文章,c# 3.0仍然是静态类型的,真的!,以及随后的系列相当不错。
这就是var的作用。其他用途可能就没这么好用了。任何与JScript、VBScript或动态类型的比较都是胡扯。再次注意,var是为了使某些其他特性在. net中工作而必需的。