在与同事讨论了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确实保持强类型,但问题是,在定义中不立即显示类型是否危险,当重载意味着当你无意中将错误的类型传递给方法时,编译器可能不会发出错误,这种情况会被放大。
我们采用了“为人编写代码,而不是为机器编写代码”的理念,基于这样的假设:在维护模式中花费的时间要比在新的开发模式中花费的时间长好几倍。
对我来说,这就排除了编译器“知道”变量是什么类型的说法——当然,你不可能第一次就写出无效的代码,因为编译器会阻止你的代码编译,但是当下一个开发人员在6个月的时间里阅读代码时,他们需要能够推断出变量做得正确或不正确的地方,并快速确定问题的原因。
因此,
var something = SomeMethod();
在我们的编码标准中是不合法的,但在我们的团队中鼓励这样做,因为它增加了可读性:
var list = new List<KeyValuePair<string, double>>();
FillList( list );
foreach( var item in list ) {
DoWork( item );
}
你最可能需要它的时候是匿名类型(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);
当你不想重复自己的时候,Var很有用。例如,我昨天需要一个类似于此的数据结构。您喜欢哪种表示法?
Dictionary<string, Dictionary<string, List<MyNewType>>> collection = new Dictionary<string, Dictionary<string, List<MyNewType>>>();
or
var collection = new Dictionary<string, Dictionary<string, List<MyNewType>>>();
请注意,在本例中使用var几乎不会引起歧义。然而,有时候这并不是一个好主意。例如,如果我像下面这样使用var,
var value= 5;
当我可以只写真正的类型,并消除任何歧义5应该如何表示。
double value = 5;