3

所以,就实际问题的问题而言,这可能不是一个很好的问题,但它困扰着我,我找不到答案,所以我认为这是一个问题。

的特殊性是var什么?关于它的MSDN 参考说明如下:

隐式类型的局部变量是强类型的,就像您自己声明了类型一样

Bur 它似乎没有在任何地方说明它是强类型的。例如,如果我有以下内容:

var x = new Tree();

但是我然后不调用任何方法Treex仍然是强类型的tree?或者我可以有类似以下的东西吗?

var x = new Tree();
x = new Object();

我猜这是不允许的,但我现在无法访问编译器,我真的想知道是否有任何警告允许出现上述意外行为。

4

6 回答 6

10

它被强类型化为右侧表达式的类型:

var 关键字指示编译器从初始化语句右侧的表达式推断变量的类型。

这里

于 2012-12-13T20:25:21.973 回答
6

它与等号右侧的类型相关联,因此在这种情况下,它等价于:

Tree x = new Tree();

无论接口或基类绑定到什么Tree。如果您需要x属于较低类型,则必须专门声明它,例如:

Plant x = new Tree();
// or
IHasLeaves x = new Tree();
于 2012-12-13T20:25:39.480 回答
2

是的,在您的示例x中,强类型为Tree just as if you had declared the type yourself.

您的第二个示例无法编译,因为您正在重新定义x.

于 2012-12-13T20:25:30.203 回答
2

不,完全一样,如果您输入了Tree x = new Tree();. 显然编译器能做的唯一明确的推断是右边表达式的确切类型,所以它不会突然变成ITree x

所以这不起作用:

Tree x = new Tree();
x = new Object(); //cannot convert implicitly

如果您很好奇,dynamic则更接近您期望的行为。

dynamic x = new Tree();
x = new Object(); 
于 2012-12-13T20:34:38.457 回答
1

在示例中:

var x = new Tree();

是相同的

Tree x = new Tree();

我发现使用“var”总是更好,因为它有助于代码重构。

此外,添加,

var x = new Object();

由于您不能两次声明变量,因此在同一范围内会破坏编译。

于 2012-12-13T20:28:23.937 回答
0

var既不是类型,也不会使变量变得特别。它告诉编译器在编译时通过分析赋值运算符右侧的初始化表达式来推断变量的类型。

这两个表达式是等价的:

Tree t = new Tree();

var t = new Tree();

就我个人而言,我更喜欢var在右侧明确提及类型名称或确切类型复杂且与 LINQ 查询返回的结果不真正相关时使用。这些 LINQ 结果通常只是进一步处理的中间结果:

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

比下面的陈述更容易阅读,而且非常清楚:

Dictionary<string, List<int>> x = new Dictionary<string, List<int>>();
var query = someSource
    .Where(x => x.Name.StartsWith("A"))
    .GroupBy(x => x.State)
    .OrderBy(x => x.Date);

这里query是类型IOrderedEnumerable<IGrouping<string, SomeType>>。谁在乎?


当类型名称没有出现在右侧并且很简单时,我更喜欢明确地编写它,因为它不会简化任何使用var

int y = 7;
string s = "hello";

当然,如果您创建匿名类型,则必须使用var,因为您没有类型名称:

var z = new { Name = "Coordinate", X = 5.343, Y = 76.04 };

关键字与 LINQ 一起引入是var为了简化它们的使用并允许动态创建类型以模拟您使用 SQL 的方式:

SELECT Name, Date FROM Person
var result = DB.Persons.Select(p => new { p.Name, p.Date });
于 2012-12-13T20:48:24.283 回答