在与同事讨论了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确实保持强类型,但问题是,在定义中不立即显示类型是否危险,当重载意味着当你无意中将错误的类型传递给方法时,编译器可能不会发出错误,这种情况会被放大。
var是处理匿名类型的方法,无论是否来自LINQ语句。任何其他用途在很大程度上取决于谁将阅读您的代码以及有哪些指导方针。
如果你是唯一的观众,或者你的观众对使用var很熟悉,或者非常熟悉你的代码,那么我想这没有关系。如果你像这样使用:var s = new SqlConnection(),那么这在很大程度上无关紧要,可能会提高代码的可读性。如果人们不太挑剔,他们可以做一些工作来了解不明显的类型(这在大多数情况下是不需要的,你在下面的语句中如何使用它通常会解释一切),那么它是好的。
但是如果你有挑剔的,思想封闭的队友,他们喜欢抱怨,或者如果你公司的设计准则特别禁止在类型不明显时使用var,那么你很可能会遇到强烈的反对。
如果使用var会让你的代码难以阅读,你可能会因为使用var而受到伤害,即使这可能是你的应用程序设计的问题。
如果var引入了歧义(有点像你的IEnumerable/IEnumerable例子),不要使用它,而是显式地使用它。但var确实有它的便利,在某些情况下,恕我直言,它甚至可以通过减少混乱来提高可读性。
从关于这一主题的讨论来看,结果似乎是:
Good: var customers = new List<Customer>();
争议性:var customers = dataAccess.GetCustomers();
忽略“var”神奇地帮助重构的错误观点,对我来说最大的问题是人们坚持认为他们不关心返回类型是什么,“只要他们能枚举集合”。
考虑:
IList<Customer> customers = dataAccess.GetCustomers();
var dummyCustomer = new Customer();
customers.Add(dummyCustomer);
现在考虑:
var customers = dataAccess.GetCustomers();
var dummyCustomer = new Customer();
customers.Add(dummyCustomer);
现在,重构数据访问类,使GetCustomers返回IEnumerable<Customer>,看看会发生什么……
这里的问题是,在第一个示例中,您明确了对GetCustomers方法的期望—您说您希望它返回一些行为类似于列表的东西。在第二个示例中,这个期望是隐式的,从代码中不能立即看出。
(对我来说)有趣的是,许多支持var的论点说“我不在乎它返回什么类型”,但接着说“我只需要迭代它……”。(因此它需要实现IEnumerable接口,这意味着类型很重要)。