在与同事讨论了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很有用。例如,我昨天需要一个类似于此的数据结构。您喜欢哪种表示法?

Dictionary<string, Dictionary<string, List<MyNewType>>> collection = new Dictionary<string, Dictionary<string, List<MyNewType>>>();

or

var collection = new Dictionary<string, Dictionary<string, List<MyNewType>>>();

请注意,在本例中使用var几乎不会引起歧义。然而,有时候这并不是一个好主意。例如,如果我像下面这样使用var,

var value= 5;

当我可以只写真正的类型,并消除任何歧义5应该如何表示。

double value = 5;

其他回答

局部变量可以被赋予一个推断的var“类型”,而不是一个显式的类型。关键字var指示编译器从初始化语句右边的表达式推断变量的类型。

// z被编译为int类型

var z = 100;

// s被编译为下面的字符串

var s = "Hello";

// a被编译为int[]

var a = new[] { 0, 1, 2 };

// expr被编译为IEnumerable //或者IQueryable

var expr =
    from c in customers
    where c.City == "London"
    select c;

// anon被编译为匿名类型

var anon = new { Name = "Terry", Age = 34 };

// list被编译为list

var list = new List<int>();

var can only be used when a local variable is declared and initialized in the same statement; the variable cannot be initialized to null, or to a method group or an anonymous function.

Var不能在类范围内的字段上使用。

使用var声明的变量不能在初始化表达式中使用。换句话说,这个表达式是合法的:int i = (i = 20);但是这个表达式会产生一个编译时错误:var I = (I = 20);

多个隐式类型变量不能在同一个语句中初始化。

如果一个名为var的类型在作用域中,那么var关键字将解析为该类型名称,并且不会被视为隐式类型局部变量声明的一部分。

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

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

var i = 5;
int j = 5;

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

...完全是主观的。

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

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.

您可以让编译器(以及接下来维护代码的人员)从初始化式赋值的右边推断类型。如果这种推断是可能的,编译器可以这样做,从而节省了您的一些输入。

如果这个推断对那个可怜的家伙来说很容易,那么你没有伤害到任何东西。如果推断很难,那么作为一般规则,您已经使代码更难维护 我不会这么做的。

Lastly, if you intended the type to be something particular, and your initializer expression actually has a different type, using var means it will be harder for you to find the induced bug. By explicitly telling the compiler what you intend the type to be, when the type isn't that, you would get an immediate diagnostic. By sluffing on the type declaration and using "var", you won't get an error on the initialization; instead, you'll get a type error in some expression that uses the identifier assigned by the var expression, and it will be harder to understand why.

寓意是,要谨慎使用var;您通常不会给您自己或您的下游维护人员带来很多好处。并希望他的理由是一样的,这样你就不会因为他认为使用var很容易而猜测他的意图。在编写一个具有较长生命周期的系统时,优化输入量是一个错误。

在做了十年的Java专业人员之后,我在c#世界里还是个新手。我最初的想法是“哦,不!这就把类型安全丢进了下水道”。然而,我对var了解得越多,我就越喜欢它。

1) Var与显式声明的类型一样是类型安全的。这都是关于编译时语法糖。

2)遵循DRY原则(不要重复)。DRY是关于避免冗余的,在两边都命名类型肯定是冗余的。避免冗余就是要让你的代码更容易修改。

3)至于确切的型号……嗯. .我认为你应该有一个大致的概念你有一个整数,一个套接字,一些UI控件,等等。智能感知将从这里引导你。知道确切的类型通常并不重要。例:我认为99%的情况下你并不关心给定的变量是long还是int, float还是double。对于最后1%的情况,在真正重要的地方,只需将鼠标指针悬停在var关键字上方。

4)我曾看到过这样一种荒谬的观点:现在我们需要回到1980年风格的匈牙利疣,才能区分变量类型。毕竟,在蒂莫西·道尔顿(Timothy Dalton)扮演詹姆斯·邦德(James Bond)的时代,这是判断变量类型的唯一方法。但现在是2010年。我们已经学会了根据变量的用法和内容来命名变量,并让IDE指导我们确定它们的类型。只要继续这样做,var就不会伤害你。

总而言之,var不是什么大东西,但它确实是一个很好的东西,而且它是Java最好很快复制的东西。所有反对的观点似乎都是基于ide之前的谬误。我会毫不犹豫地使用它,我很高兴R#帮助我做到这一点。