在C#中使用var关键字
在与同事讨论在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;
这并不比equivilent foreach(var中的someList){// ...} equivilent更好。
这里有一个关于类型安全的真正问题 - 例如,如果我们要将查询的结果放入一个接受IEnumerable <int>和IEnumerable <double>的重载方法中,调用方可能会无意中传入错误的类型。
var
确实保持了强类型化,但问题是这种类型在定义时不会立即显示是危险的,当重载意味着编译器错误可能在您无意中将错误类型传递给方法时可能不会发出。
在某些情况下,我仍然认为var
可以使代码更具可读性。 如果我有一个带有Orders属性的Customer类,并且我想将它分配给一个变量,我只需要这样做:
var orders = cust.Orders;
我不关心,如果Customer.Orders是IEnumerable<Order>
, ObservableCollection<Order>
或BindingList<Order>
- 我想要的是保持该列表在内存中迭代它或得到它的计数或稍后的东西。
将上述声明与以下对比:
ObservableCollection<Order> orders = cust.Orders;
对我而言,类型名称只是噪音。 如果我回去并决定改变Customer.Orders的类型(例如从ObservableCollection<Order>
到IList<Order>
),那么我需要更改该声明 - 我不需要做的事情如果我首先使用了var。
我广泛使用var
。 有人批评这会降低代码的可读性,但没有理由支持这一说法。
诚然,这可能意味着我们不清楚我们正在处理什么类型。 所以呢? 这实际上是一个分离设计的重点。 在处理接口时,你强调对变量的类型不感兴趣。 var
更进一步,这是真的,但我认为从可读性的角度来看,论点仍然是一样的:程序员实际上不应该对变量的类型感兴趣,而应该关注变量的作用。 这就是为什么微软也称为类型推断“鸭子打字”。
那么,当我使用var
声明它时,变量会做什么? 很简单,它可以做任何IntelliSense告诉我它做的事情。 任何关于C#忽略IDE的推理都不符合现实。 实际上,每个C#代码都在支持智能感知的IDE中编程。
如果我正在使用var
声明的变量并且弄不清变量是什么,那么我的代码就会出现一些根本性错误。 var
不是原因,它只是使症状可见。 不要责怪使者。
现在,C#团队已经发布了一个编码指南,指出该var
只能用于捕获创建匿名类型的LINQ语句的结果(因为这里我们没有真正的var
替代)。 那么,拧紧。 只要C#团队没有给我这个指导方针一个合理的论点,我就会忽略它,因为在我的专业和个人意见中,这纯粹是胡扯。 (对不起,我没有链接到有关的准则。)
实际上,为什么你不应该使用var
有一些(表面上)很好的解释,但我仍然认为它们在很大程度上是错误的。 以“searchabililty”为例:作者声称var
很难搜索使用MyType
地方。 对。 接口也是如此。 其实,为什么我想知道课堂在哪里? 我可能更感兴趣的是它在哪里实例化,这仍然是可搜索的,因为它的构造函数必须被调用(即使这是间接完成的,类型名称必须在某处提及)。
Var,在我看来,在C#中是一件很好的事情。 任何这样键入的变量仍然是强类型的,但是它从赋值的右侧获取它的类型。 由于类型信息在右侧可用,因此在大多数情况下,没有必要且过于冗长,因此也必须在左侧输入它。 我认为这会显着提高可读性而不会降低类型安全性。
在我看来,从可读性的角度来看,使用变量和方法的良好命名约定比显式类型信息更重要。 如果我需要类型信息,我总是可以将鼠标悬停在变量上(在VS中)并获取它。 一般来说,读者不需要明确的类型信息。 对于开发人员来说,在VS中你仍然可以获得Intellisense,无论变量是如何声明的。 尽管如此,仍然有些情况下,明确声明类型是有意义的 - 也许你有一个返回List<T>
,但是你想在你的对象中将它作为IEnumerable<T>
方法。 为了确保您使用的是接口,声明接口类型的变量可以使其变得明确。 或者,也许你想声明一个没有初始值的变量 - 因为它立刻根据某种条件得到一个值。 在这种情况下,你需要这种类型。 如果类型信息有用或必要,请继续使用它。 但我觉得,通常情况下这是没有必要的,而且在大多数情况下,没有它的代码更容易阅读。