前几天我和同事聊天,听说他们的编码标准明确禁止他们var
在C#中使用关键字.他们不知道为什么会如此,我总是发现隐式声明在编码时非常有用.我从来没有遇到任何问题,找出变量是什么类型(你只是将鼠标悬停在VS中的变量上,你会得到那种方式).
有谁知道为什么在C#中使用var关键字是个坏主意?
2008年11月发布的.Net框架设计指南(精彩的书籍)的作者建议考虑var
在类型明显且明确的时候使用.
另一方面,如果使用var
会在阅读代码时导致歧义,正如Anton Gogolev指出的那样,那么最好不要使用它.
在书中(附件A),他们实际上给出了这个例子:
var names = new List(); // good usage of var string source = GetSource(); var tokens = source.Split(' '); // ok; most developers know String.Split var id = GetId(); // Probably not good; it's not clear what the type of id is
为了确保可读性不受低级开发人员的影响,您的组织可能已经决定您不值得var
并禁止它.
但这很遗憾,它就像拥有一个漂亮的工具,但保存在一个锁着的玻璃柜中.
在大多数情况下,使用var
简单类型实际上有助于提高可读性,我们不能忘记使用时也没有性能损失var
.
var q = GetQValue();
确实是一件坏事.然而,
var persistenceManager = ServiceLocator.Resolve();
对我来说完全没问题.
底线是:使用描述性标识符名称,你会相处得很好.
作为旁注:我不知道如果不允许使用var
关键字,他们如何处理匿名类型.或者他们不完全使用它们?
在大多数情况下,当合理使用时(即类型和值相同的简单类型初始化器),那就没问题了.
有些时候不清楚你是否通过改变来破坏它 - 主要是,当初始化类型和(原始)变量类型不相同时,因为:
变量最初是基类
变量最初是一个接口
该变量最初是具有隐式转换运算符的另一种类型
在这些情况下,您可能会遇到任何类型分辨率的问题 - 例如:
对于两种竞争类型具有不同重载的方法
为两种竞争类型定义不同的扩展方法
已在其中一种类型上重新声明(隐藏)的成员
泛型类型推断将以不同的方式工作
操作员解析将以不同的方式
在这种情况下,您可以更改代码的含义,并执行不同的操作.这是一件坏事.
例子:
隐式转换:
static void Main() { long x = 17; Foo(x); var y = 17; Foo(y); // boom } static void Foo(long value) { Console.WriteLine(value); } static void Foo(int value) { throw new NotImplementedException(); }
方法隐藏:
static void Main() { Foo x = new Bar(); x.Go(); var y = new Bar(); y.Go(); // boom } class Foo { public void Go() { Console.WriteLine("Hi"); } } class Bar : Foo { public new void Go() { throw new NotImplementedException(); } }
等等
当然这是一个错误.这是因为有些人并没有意识到它实际上是强类型的,而且根本不像VB中的var.
并非所有的公司编码标准都有意义,我曾经为一家想要在公司名称前加上所有类名称的公司工作过.当公司改名时,进行了大规模的返工.
首先,作为一般规则,编码标准应该由团队讨论和同意,并且应该写下他们背后的推理,以便任何人都可以知道他们为什么在那里.他们不应该是一位大师的圣洁真理.
其次,这个规则可能是合理的,因为代码读取次数多于写入次数.var
加快写作速度,但可能会减慢读数速度.它显然不是像"始终初始化变量"这样的代码行为规则,因为两种选择(写入var
和写入类型)具有完全相同的行为.所以这不是一个关键的规则.我不会禁止var
,我会使用"首选..."
几个月前我写了一篇关于这个主题的博客文章.对我来说,我尽可能地使用它,并专门围绕类型推断设计我的API.我使用类型推断的基本原因是
它不会降低类型安全性
它实际上会通过提醒您隐式转换来增加代码中的类型安全性.foreach语句中最好的例子
在C#中维持DRY原则.这是专门针对宣言的案例,为什么还要两次说这个名字呢?
在某些情况下,它是必需的.示例匿名类型
减少打字而不损失功能.
http://blogs.msdn.com/jaredpar/archive/2008/09/09/when-to-use-type-inference.aspx
var
是最新的"如何布置你的大括号"/匈牙利符号/骆驼套管辩论.没有正确的答案,但有些人坐在极端.
你的朋友很幸运,他们在一个极端分子之下工作.
禁止它完全意味着禁止使用匿名类型(当你更多地使用LINQ时,它变得非常有用).
这是愚蠢的简单和简单,除非有人可以正式确定永远不使用匿名类型的正当理由.