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


当前回答

Kronoz -在这种情况下(两者都重载)会有问题吗?如果你有两个不同类型的重载,本质上你会说任何一个都可以被传递,做同样的事情。

不应该有两个重载根据传递的类型执行完全不同的操作。

虽然在这种情况下您可能会感到困惑,但它仍然是完全类型安全的,只是有人调用了错误的方法。

其他回答

来自Essential LINQ:

除非绝对必要,否则最好不要显式声明范围变量的类型。例如,下面的代码编译干净,但是编译器可以在没有正式声明的情况下推断出类型:

List<string> list = new List<string> { "LINQ", "query", "adventure" };
var query = from string word in list
      where word.Contains("r")
      orderby word ascending
      select word;

显式声明range变量的类型会强制对LINQ Cast操作符进行幕后调用。此调用可能会产生意想不到的结果,并可能会损害性能。如果您在LINQ查询中遇到性能问题,像这里所示的强制转换可能是开始寻找罪魁祸首的一个地方。(此规则的一个例外是当您使用非泛型Enumerable时,在这种情况下您应该使用强制转换。)

在IEnumerable<int>和IEnumerable<double>之间的比较中,你不需要担心-如果你传递了错误的类型,你的代码无论如何都不会编译。

不需要考虑类型安全,因为var不是动态的。这只是编译器的魔法,任何类型不安全的调用都会被捕获。

Linq绝对需要Var:

var anonEnumeration =
    from post in AllPosts()
    where post.Date > oldDate
    let author = GetAuthor( post.AuthorId )
    select new { 
        PostName = post.Name, 
        post.Date, 
        AuthorName = author.Name
    };

现在看看智能感知中的anonEnumeration,它会显示类似IEnumerable<'a>

foreach( var item in anonEnumeration ) 
{
    //VS knows the type
    item.PostName; //you'll get intellisense here

    //you still have type safety
    item.ItemId;   //will throw a compiler exception
}

c#编译器非常聪明——单独生成的anon类型如果它们的属性匹配,将具有相同的生成类型。

除此之外,只要你有智能感知,在上下文清楚的地方使用var是有意义的。

//less typing, this is good
var myList = new List<UnreasonablyLongClassName>();

//also good - I can't be mistaken on type
var anotherList = GetAllOfSomeItem();

//but not here - probably best to leave single value types declared
var decimalNum = 123.456m;

我广泛使用var。有人批评这降低了代码的可读性,但没有证据支持这种说法。

Admittedly, it may mean that it's not clear what type we are dealing with. So what? This is actually the point of a decoupled design. When dealing with interfaces, you are emphatically not interested in the type a variable has. var takes this much further, true, but I think that the argument remains the same from a readability point of view: The programmer shouldn't actually be interested in the type of the variable but rather in what a variable does. This is why Microsoft also calls type inference “duck typing.”

当我用var声明变量时,它会做什么呢?简单,智能感知让它做什么它就做什么。任何关于c#的推理都忽略了IDE,这是不现实的。实际上,每个c#代码都是在支持智能感知的IDE中编写的。

如果我使用了一个var声明的变量,并对变量的用途感到困惑,那么我的代码就有根本性的问题。Var不是原因,它只是使症状可见。不要责怪送信的人。

现在,c#团队发布了一个编码指南,声明var应该只用于捕获创建匿名类型的LINQ语句的结果(因为在这里,我们没有真正的替代var的方法)。去他的。只要c#团队没有给我一个合理的论证,我就会忽略它,因为在我的专业和个人观点中,这纯粹是胡扯。(抱歉;我找不到相关指南的链接。)

Actually, there are some (superficially) good explanations on why you shouldn't use var but I still believe they are largely wrong. Take the example of “searchabililty”: the author claims that var makes it hard to search for places where MyType is used. Right. So do interfaces. Actually, why would I want to know where the class is used? I might be more interested in where it is instantiated and this will still be searchable because somewhere its constructor has to be invoked (even if this is done indirectly, the type name has to be mentioned somewhere).

我同意马特·汉密尔顿的观点。

当使用好的变量名时,Var可以使您的代码更具可读性和可理解性。但是,如果使用不当,var也会使您的代码像Perl一样难以阅读和理解。

一个var的好的和坏的用法列表也不会有太大的帮助。这是一个常识问题。更大的问题是可读性和可写性。许多开发者并不关心他们的代码是否具有可读性。他们只是不想打那么多。就我个人而言,我是一个读,写,写的人。

取决于,它使代码看起来“更干净”,但同意它使它更难以读…