似乎我阅读的 C# 代码越来越多地使用var类型标识符:
foreach (var itemChange in ItemChanges)
{
//...
}
而不是明确说明类型:
foreach (ItemChange itemChange in ItemChanges)
{
//...
}
即使类型已知。
我仍在使用后一个显式版本,只是因为我认为稍后阅读它的人会比使用 var 更快地理解变量的类型。
但是有任何技术理由使用其中一种吗?
似乎我阅读的 C# 代码越来越多地使用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 是 C# 3.0 的特性,仅在匿名类型中是必需的
因为下面的代码
var v = new { Amount = 108, Message = "Hello" };
动态创建一个新的匿名类型,var 使用是强制性的。例如, var 在通常动态创建类型的 Linq 中特别有用。
在任何其他情况下,这只是最终应用程序的喜好问题(在编译期间已解决)。但是对于代码阅读器,我认为 'var' 类型本身的信息量较少。
一般没有技术原因。可读性——在任何一个方向上——是唯一真正的因素。
但是,一个小警告是这var
将推断变量的静态类型。如果您想要子类或超类类型,则需要自己进行转换。在 a 的情况下foreach
,如在您的示例中,您通常可以通过使用子类类型声明循环变量来“免费”为您执行向下转换。
典型的例子是遍历一个 XML NodeList,你知道它是一个 的列表XmlElement
,但Nodelist
它被键入为一个XmlNode
s 的集合。当然,您可以使用强制转换或 anas
来取回您想要的类型,但这似乎违背了使用类型推断的目的:-)
当然,一旦您尝试使用仅可用于的节点成员,编译器就会让您知道这一点XmlElement
- 所以它仍然不是严格的技术差异。
另一件有点烦人的事情是,如果你使用像 Resharper 这样的工具,它会非常激进地建议你var
在所有可能的情况下使用。当它建议您更改时尤其烦人,例如,将int
声明更改为var
!
但是,除非您关闭该功能,否则您使用的次数越多,Resharper 的“噪音”就会越少var
。
我知道的唯一技术原因是您可以在没有 的情况下执行隐式转换var
,例如
int i = 5;
double a = i; // implicit cast with explicit types
但在这里我更喜欢var
它,因为它使演员表明确;虽然我不太关心在执行表示更改类型转换时我关心的类型:
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 => ...);
或者您是否乐意让编译器为您做一些工作并让它计算出类型,而代价是没有明确说明类型信息?
如果您对 linq 和泛型方法中的类型推断感到满意,那么您已经决定可以不用在任何地方明确说明类型,并且您可能还没有发现代码的可读性降低结果(事实上,您可能发现完全相反)。因此,使用var
只是在您已经走的同一条道路上的又一步。
不var
,在提高可读性的地方使用,反之亦然。
var 是 C# 3.x+ 的一个特性,不是吗?如果不使用它,您的代码也与其他版本更兼容。
SO中有很多有趣的问题,当你搜索“ var C# ”时
除了匿名类型之外,在程序的任何给定状态下都没有使用 var 的技术原因。
但是,使用 var 可以让程序在您无需编辑的情况下进行更改。给定
public int SomeMethod(){}
public List<T> SomeOtherMethod<T>(T parameter);
然后
var x = SomeMethod();
var y = SomeOtherMethod(x);
会工作(你会List<int>
)。如果你用过
int x = SomeMethod();
List<int> y = SomeOtherMethod(x);
那么如果SomeMethod()
被改成 return long
,那么你就必须改变 y 的定义。
我已经看到这种事情在整个程序中传播,需要进行数百次更改。特殊情况是将数据访问代码更改为 returnReadOnlyCollection<T>
而不是List<T>
. 需要进行很多代码更改,我将所有明确提及的内容都更改List<T>
为 var,并且代码永远不需要再次更改。