在与同事讨论了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确实保持强类型,但问题是,在定义中不立即显示类型是否危险,当重载意味着当你无意中将错误的类型传递给方法时,编译器可能不会发出错误,这种情况会被放大。
从关于这一主题的讨论来看,结果似乎是:
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接口,这意味着类型很重要)。
我不明白这有什么大不了的。
var something = someMethod(); // Type of 'something' not clear <-- not to the compiler!
你仍然对“某事”有完全的智能感知,对于任何不明确的情况,你都有单元测试,对吗?(是吗?)
它不是varchar,也不是dim,当然也不是动态或弱类型。它像这样阻止疯狂的人:
List<somethinglongtypename> v = new List<somethinglongtypename>();
把这些杂乱的思想归纳为:
var v = new List<somethinglongtypename>();
不错,但不如:
v = List<somethinglongtypename>();
但这就是布的作用。
来自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中工作而必需的。