在与同事讨论了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确实保持强类型,但问题是,在定义中不立即显示类型是否危险,当重载意味着当你无意中将错误的类型传递给方法时,编译器可能不会发出错误,这种情况会被放大。


当前回答

好吧,这个问题会一直固执己见,但我会试着给出我的观点-尽管我认为我的观点是如此混乱,你可能不会从中得到什么。

首先——有匿名类型,为此你需要使用“var”关键字来分配一个匿名类型作为类的对象——这里没有太多的讨论,“var”是必要的。

然而,对于更简单的类型,如int型、长型、字符串型等等,我倾向于输入适当的类型。主要是因为它有点像“懒人的工具”,我在这里看不到太多的好处,很少的按键和它可能带来的困惑,这是不值得的。特别是浮点数的各种类型(浮点数、双精度数、十进制数)使我感到困惑,因为我对字面量中的后缀不坚定——我喜欢在源代码中看到类型。

话虽如此,如果类型更复杂和/或它显式地重复在赋值的右侧,我倾向于大量使用var。这可以是一个List<string>或etc,例如:

var list = new List<string>();

在这种情况下,我认为没有必要重复类型两次——特别是当您开始更改代码和类型更改时——泛型类型可能会变得越来越复杂,因此必须更改它们两次只是一种痛苦。当然,如果你希望针对IList<string>编码,那么你必须显式地命名类型。

简而言之,我做了以下事情:

当类型很短或不能脱离上下文读取时,显式地命名类型 在必要时使用var(废话) 当var(在我看来)不影响可读性时,使用它来偷懒

其他回答

当我开始使用var关键字时,我也有同样的担忧。 然而,随着时间的推移,我已经习惯了它,不打算回到显式变量类型。 Visual Studio的编译器\智能感知在使隐式类型变量的工作更容易方面做得非常好。

我认为遵循正确的命名约定可以帮助您更好地理解代码,而不是显式键入。

这似乎是类似于“我应该在变量名中使用前缀吗?”这样的问题。 坚持使用好的变量名,让编译器考虑变量类型。

我发现使用var关键字实际上使代码更具可读性,因为你只是习惯于跳过'var'关键字。当您真的不关心具体类型是什么时,您不需要一直向下滚动来弄清楚代码在做什么。如果我真的需要知道下面的“item”是什么类型,我只需将鼠标悬停在它上面,Visual Studio就会告诉我。换句话说,我更愿意读书

foreach( var item in list ) { DoWork( item ); }

一遍又一遍地

foreach( KeyValuePair<string, double> entry in list ) { DoWork( Item ); }

当我试图消化代码时。我认为这在某种程度上可以归结为个人喜好。在这一点上,我将依赖常识——在重要的方面(安全性、数据库使用、日志记录等)保留强制标准。

-工业。

考虑到智能感知现在是多么强大,我不确定var是否比在一个类中拥有成员变量或在一个方法中定义在可见屏幕区域之外的局部变量更难阅读。

如果你有一行代码,比如

IDictionary<BigClassName, SomeOtherBigClassName> nameDictionary = new Dictionary<BigClassName, SomeOtherBigClassName>();

Is比以下更容易或更难读:

var nameDictionary = new Dictionary<BigClassName, SomeOtherBigClassName>();

我们采用了“为人编写代码,而不是为机器编写代码”的理念,基于这样的假设:在维护模式中花费的时间要比在新的开发模式中花费的时间长好几倍。

对我来说,这就排除了编译器“知道”变量是什么类型的说法——当然,你不可能第一次就写出无效的代码,因为编译器会阻止你的代码编译,但是当下一个开发人员在6个月的时间里阅读代码时,他们需要能够推断出变量做得正确或不正确的地方,并快速确定问题的原因。

因此,

var something = SomeMethod();

在我们的编码标准中是不合法的,但在我们的团队中鼓励这样做,因为它增加了可读性:

var list = new List<KeyValuePair<string, double>>();
FillList( list );
foreach( var item in list ) {
   DoWork( item ); 
}

Var对于匿名类型是必不可少的(正如之前对这个问题的回答之一所指出的那样)。

我会把所有其他关于宗教战争利弊的讨论归类为“宗教战争”。我的意思是对……的相对优点进行比较和讨论。

var i = 5;
int j = 5;

SomeType someType = new SomeType();
var someType = new SomeType();

...完全是主观的。

隐式类型意味着使用var关键字声明任何变量都不会在运行时造成损失,因此归根结底,这是一个关于如何让开发人员满意的争论。