在与同事讨论了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可以节省时间的狂热爱好者来说,它可以减少敲击键盘的次数:

StringBuilder sb = new StringBuilder();

than

var sb = new StringBuilder();

如果你不相信,你可以数数……

19对21

如果有必要我会解释的,但你试试吧……(取决于你的智能感知的当前状态,你可能需要为每一个输入更多)

你能想到的每一种类型都是如此!!

我个人的感觉是,除非在不知道类型的情况下,否则永远不应该使用var,因为它降低了代码中的识别可读性。大脑识别字体的时间比识别一整行字体要长。那些懂机器码和比特的老家伙知道我在说什么。大脑是并行处理的,当你使用var时,你强迫它序列化它的输入。为什么会有人想让自己的大脑更努力地工作呢?这就是电脑的作用。

其他回答

在大多数情况下,只是输入它更简单——想象一下

var sb = new StringBuilder();

而不是:

StringBuilder sb = new StringBuilder();

有时它是必需的,例如:匿名类型,比如。

var stuff = new { Name = "Me", Age = 20 };

我个人喜欢使用它,尽管它会降低代码的可读性和可维护性。

来自c#团队的高级软件设计工程师Eric Lippert:

为什么引入var关键字?

There are two reasons, one which exists today, one which will crop up in 3.0. The first reason is that this code is incredibly ugly because of all the redundancy: Dictionary<string, List<int>> mylists = new Dictionary<string, List<int>>(); And that's a simple example – I've written worse. Any time you're forced to type exactly the same thing twice, that's a redundancy that we can remove. Much nicer to write var mylists = new Dictionary<string,List<int>>(); and let the compiler figure out what the type is based on the assignment. Second, C# 3.0 introduces anonymous types. Since anonymous types by definition have no names, you need to be able to infer the type of the variable from the initializing expression if its type is anonymous.

我特别强调。整篇文章,c# 3.0仍然是静态类型的,真的!,以及随后的系列相当不错。

这就是var的作用。其他用途可能就没这么好用了。任何与JScript、VBScript或动态类型的比较都是胡扯。再次注意,var是为了使某些其他特性在. net中工作而必需的。

这是个人品味的问题。当您习惯了动态类型的语言后,所有关于变量类型的烦恼都消失了。也就是说,如果你开始喜欢他们(我不确定是不是每个人都可以,但我喜欢)。

c#的var非常酷,因为它看起来像动态类型,但实际上是静态类型——编译器会强制正确使用。

变量的类型并不是那么重要(这在前面已经说过了)。从上下文(它与其他变量和方法的交互)和它的名称来看,它应该相对清晰——不要期望customerList包含int…

我还在等着看我的老板对这件事的看法——我得到了一个全面的“允许”,可以在3.5中使用任何新的结构,但是我们将如何维护呢?

在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;

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

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

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