我从this question知道var i = 1
和int i = 1
在IL中完全相同。编译器只是在编译时用实际类型替换var
。但是,是否存在var
可能导致问题行为的任何情况(编译器可能猜错类型?)
答案 0 :(得分:8)
我不相信编译器会猜错类型。但是,它可能会推断出你不想要的类型,但那不一样。
考虑完全合法的
decimal foo = 10;
decimal bar = 4;
decimal baz = foo / bar;
在代码中,baz
非常明显是2.5。整数文字将在存储之前转换为小数,然后数学发生在十进制值上。删除显式输入,结果不同。
var foo = 10;
var bar = 4;
var baz = foo / bar;
现在一切都推断为int而baz
是2,因为现在数学是用整数进行的。
所以,是的,如果你引入var
之前的代码语义,理论上可能会改变。所以关键是要了解什么类型的推断实际上与你的代码有关,如果你想要一些小数(或任何特定的类型X),请以这样的方式声明它。对于类型推断,那将是
var foo = 10m;
答案 1 :(得分:2)
不,我不这么认为。只有当你尝试做类似
之类的事情时,它才能解决问题var product = null;
这是有道理的,在这种情况下,您会收到编译错误。
答案 2 :(得分:2)
对于代码,它不会引起任何“问题”,但是你可能会出现回归问题......
IObject1
{
void DoSomething();
}
IObject2
{
void DoSomething();
}
var result = SomeMethod();
result.DoSomething();
现在,如果SomeMethod返回IObject1然后更改为返回IObject2,那么仍然会编译。 然而 ,如果您希望DoSomething执行特定代码,那么这可能是一个回归问题。
但是,如果你有
IObject1 result = SomeMethod();
如果更改SomeMethod的返回类型,您将立即知道它。
答案 3 :(得分:1)
除了含糊之处:
var x = null;
编译器也不会推断重载方法组的类型:
var m = String.Equals;
也不会推断lambda表达式的类型,可以是Func<>
或Expression<Func<>>
:
var l = (int x) => x + 1;
所有这一切,安东尼是对的:编译器永远不会做错误的事情,尽管它可能不会做你期望的事情。如有疑问,请将鼠标悬停在VS中的var
上以查看静态类型。
答案 4 :(得分:0)
var x = 0
x = 0.10
Cannot convert source type 'double' to target type 'int'
一个例子:
double x = 0; //to initialize it
switch (something) {
case condition1:
x = 0.1;
break;
case condition2:
x = 0.2;
break;
}
使用var
代替double
会产生编译错误。