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


当前回答

@erlando,出于好奇,为什么你需要知道变量的类型看源代码?

在我的实践中,我发现变量类型只在我在代码中使用它的时候对我来说是重要的。

如果我试图做一些不适当的操作在某些evar编译器欣然给我一个错误\警告。

我真的不关心someVar有什么类型,如果我明白为什么它被使用在给定的上下文中。

其他回答

你最可能需要它的时候是匿名类型(100%需要);但它也避免了琐碎案件的重复,IMO使界限更加清晰。对于简单的初始化,我不需要看到类型两次。

例如:

Dictionary<string, List<SomeComplexType<int>>> data = new Dictionary<string, List<SomeComplexType<int>>>();

(请不要编辑上面的hscroll -它有点证明了这一点!!)

vs:

var data = new Dictionary<string, List<SomeComplexType<int>>>();

然而,在某些情况下,这是一种误导,并可能导致错误。如果原始变量和初始化类型不相同,请谨慎使用var。例如:

static void DoSomething(IFoo foo) {Console.WriteLine("working happily") }
static void DoSomething(Foo foo) {Console.WriteLine("formatting hard disk...");}

// this working code...
IFoo oldCode = new Foo();
DoSomething(oldCode);
// ...is **very** different to this code
var newCode = new Foo();
DoSomething(newCode);

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

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

一遍又一遍地

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

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

-工业。

Var,在我看来,在c#中是一个很好的东西。任何这样类型的变量仍然是强类型的,但是它从赋值函数的右边得到它的类型。因为类型信息在右侧可用,在大多数情况下,也必须在左侧输入它是不必要的和过于冗长的。我认为这在不降低类型安全性的情况下显著提高了可读性。

From my perspective, using good naming conventions for variables and methods is more important from a readability perspective than explicit type information. If I need the type information, I can always hover over the variable (in VS) and get it. Generally, though, explicit type information shouldn't be necessary to the reader. For the developer, in VS you still get Intellisense, regardless of how the variable is declared. Having said all of that, there may still be cases where it does make sense to explicitly declare the type -- perhaps you have a method that returns a List<T>, but you want to treat it as an IEnumerable<T> in your method. To ensure that you are using the interface, declaring the variable of the interface type can make this explicit. Or, perhaps, you want to declare a variable without an initial value -- because it immediately gets a value based on some condition. In that case you need the type. If the type information is useful or necessary, go ahead and use it. I feel, though, that typically it isn't necessary and the code is easier to read without it in most cases.

对于LINQ,使用var的另一个很好的理由是编译器可以更优化查询。

如果你使用一个静态列表来存储结果,它将在你分配给列表的地方执行,但是使用var,它可以潜在地将原始查询与代码中后面的查询合并,从而对数据库进行更优化的查询。

我有一个例子,我在第一个查询中提取了一些数据,然后循环遍历并请求更多数据以打印出一个表。

LINQ合并了这些,所以第一个只提取id。

然后在循环中,它添加了一个我没有在那里做的额外连接来获取我包含在原始数据中的数据。

经过测试,这种方法效率更高。

如果我们没有使用var,它就会像我们写的那样进行查询。

它可以使代码更简单、更短,特别是对于复杂的泛型类型和委托。

此外,它使变量类型更容易更改。