当类型已知时,是否有任何技术理由在C#中使用或不使用var?
似乎我读到越来越多的C代码使用var类型标识符:当类型已知时,是否有任何技术理由在C#中使用或不使用var?,c#,conventions,var,C#,Conventions,Var,似乎我读到越来越多的C代码使用var类型标识符: foreach (var itemChange in ItemChanges) { //... } 而不是显式地说明类型: foreach (ItemChange itemChange in ItemChanges) { //... } 即使已知类型 我仍然使用后一个显式版本,只是因为我认为稍后阅读它的人会比使用var更快地理解变量的类型 但是,是否有任何技术上的理由使用其中一个呢?不,只是可读性。没有技术上的理由。如果在编译
foreach (var itemChange in ItemChanges)
{
//...
}
而不是显式地说明类型:
foreach (ItemChange itemChange in ItemChanges)
{
//...
}
即使已知类型
我仍然使用后一个显式版本,只是因为我认为稍后阅读它的人会比使用var更快地理解变量的类型
但是,是否有任何技术上的理由使用其中一个呢?不,只是可读性。没有技术上的理由。如果在编译时无法推断类型,则代码将不会编译 您说得对,在某些情况下,使用显式类型以提高可读性可能更好,例如
var obj = SomeMethod(); // what's the type? you'd have to inspect SomeMethod()
SomeClass obj = SomeMethod(); // the type is obvious
但在其他情况下,使用var是非常有意义的,例如
var obj = new SomeClass(); // the type is obvious
SomeClass obj = new SomeClass(); // the duplication of type is unnecessary
不。在提高可读性的地方使用
var
,反之亦然。var是C#3.x+功能,不是吗?如果不使用它,您的代码也会与其他版本更兼容
所以,当你搜索“时,这里有很多有趣的问题,通常没有技术原因。可读性——在任何一个方向上——是唯一真正的因素 然而,一个小警告是,
var
将推断变量的静态类型。如果你想要一个次级或超级类类型,你需要自己做演员。对于foreach
,如您的示例所示,您通常可以通过使用子类类型声明循环变量来“免费”执行向下转换
经典的例子是迭代XML节点列表,您知道它是XmlElement
的列表,但是NodeList
是作为XmlNode
的集合键入的。当然,您可以使用强制转换或as
来获取所需的类型,但这似乎违背了使用类型推断的目的:-)
当然,只要您尝试使用仅对xmlement
可用的节点成员,编译器就会让您知道这一点,因此严格来说,这并不是技术上的区别
另一件有点烦人的事情是,如果你使用像Resharper这样的工具,建议你在任何可能的情况下都使用
var
是非常激进的。当它建议您将int
声明更改为var
时,尤其令人讨厌
但是,除非您关闭该功能,否则使用
var
越多,您从Resharper获得的“噪音”就会越少。我知道的唯一技术原因是,您可以在不使用var
的情况下执行隐式强制转换,例如
int i = 5;
double a = i; // implicit cast with explicit types
但在这里,我更喜欢var
,因为它使cast显式化;虽然我不太关心类型,但在执行表示形式更改类型转换时,我确实关心:
var a = (double)i; // explicit cast with implicit types
但正如你所说,一般原因是可读性。你需要问自己的问题是,为什么你认为确切的具体类型对可读性很重要?您是否总是编写Linq查询来调用具体类型,例如
from ItemChange itemChange in ItemChanges
// instead of
from itemChange in ItemChanges
类似地,您是否总是调用泛型方法的类型参数,而不是使用类型推断,例如
ItemChanges.Select<ItemChange, ItemChange>((ItemChange itemChange) => ...);
// instead of
ItemChanges.Select(itemChange => ...);
ItemChanges.选择((ItemChange ItemChange)=>…);
//而不是
选择(itemChange=>…);
或者,您是否愿意让编译器为您做一些工作,并让它计算出类型,而“牺牲”的是没有明确说明类型信息
如果您对linq和泛型方法中的类型推断感到满意,那么您已经做出决定,不必在任何地方都显式地拼写类型,并且您可能还没有发现代码的可读性因此降低(事实上,您可能发现恰恰相反)。因此,使用var
只不过是沿着你已经走上的同一条道路迈出的又一步。var是C#3.0的一项功能,只有在匿名类型中才是必需的
因为下面的代码
var v = new { Amount = 108, Message = "Hello" };
动态创建新的匿名类型,必须使用var。例如,var在Linq中特别有用,其中类型通常是动态创建的
在任何其他情况下,这只是最终应用程序的品味问题(在编译期间解决)。但是对于代码读者,我认为“var”本身的信息量要小一些。在程序的任何给定状态下,除了匿名类型之外,没有任何技术理由使用var 但是,使用var允许程序在不需要编辑的情况下进行更改。给定
public int SomeMethod(){}
public List<T> SomeOtherMethod<T>(T parameter);
将起作用(y将是列表
)。如果你用过
int x = SomeMethod();
List<int> y = SomeOtherMethod(x);
intx=SomeMethod();
列表y=其他方法(x);
然后,如果将SomeMethod()
更改为返回long
,则必须更改y的定义
我见过这种东西在整个程序中传播,需要数百次更改。具体情况是将数据访问代码更改为返回
ReadOnlyCollection
,而不是List
。需要修改的代码太多了,所以我把所有明确提到的List
都改成了var,代码再也不需要修改了。它实际上是一个C#3特性,但如果你是针对.Net 2.0的,它仍然可以很好地工作。嗯,var是作为一种编译器技巧在.Net 2.0中实现的,我们偶尔会在.Net2.0应用程序中使用它。但是(a)这只是证明SomeMethod
的名称很糟糕,而不是类型信息很有用,以及(b)您为什么关心具体的类型?我看到了很多关于var
争论的答案,这些答案假设具体类型的信息有助于可读性,而没有引用任何证据证明确实如此。动态语言和函数语言的用户倾向于强烈反对内联类型信息是件好事的断言。我理解您来自何方,但是a)您可能无法控制
int x = SomeMethod();
List<int> y = SomeOtherMethod(x);