好吧,对于你们中的一些人来说这可能是显而易见的,但我对这个相当简单的代码所带来的行为感到难过:
public static void Main(string[] args)
{
int? n = 1;
int i = 1;
n = ++n - --i;
Console.WriteLine("Without Nullable<int> n = {0}", n); //outputs n = 2
n = 1;
i = 1;
n = ++n - new Nullable<int>(--i);
Console.WriteLine("With Nullable<int> n = {0}", n); //outputs n = 3
Console.ReadKey();
}
我将两个输出都显示为相同且等于2
但奇怪的是它们不是。new
。有人可以解释原因吗?
编辑:虽然生成这种“怪异”行为的代码无疑是人为设计的,但它确实看起来像C#编译器中的一个错误,虽然看似不重要,但原因似乎是内联{{1正如James最初所指出的那样。但行为不仅限于运营。方法调用的行为方式完全相同,也就是说,只调用一次它们时会被调用两次。
考虑以下重复:
public static void Main()
{
int? n = 1;
int i = 1;
n = n - new Nullable<int>(sideEffect(ref i));
Console.WriteLine("With Nullable<int> n = {0}", n);
Console.ReadKey();
}
private static int sideEffect(ref int i)
{
Console.WriteLine("sideEffect({0}) called", i);
return --i;
}
果然,输出为2
,应为1
,"sideEffect(i) called"
打印两次。
答案 0 :(得分:20)
编辑:团队已经确认这是编译器中的错误。它在罗斯林修复。要解决此问题,请使用强制转换(int?)(--i)
来阻止错误显示,或者首先将其明确地转换为Nullable<int>
。
第一个代码块在反射器中生成以下内容:
int? nullable3;
int? nullable = 1;
int num = 1;
int? nullable2 = nullable;
nullable2 = nullable = nullable2.HasValue
? new int?(nullable2.GetValueOrDefault() + 1)
: ((int?) (nullable3 = null));
int num2 = --num;
nullable = nullable2.HasValue
? new int?(nullable2.GetValueOrDefault() - num2)
: ((int?) (nullable3 = null));
Console.WriteLine("Without Nullable<int> n = {0}", nullable);
以下第二个:
nullable = 1;
num = 1;
nullable2 = nullable;
nullable2 = nullable = nullable2.HasValue
? new int?(nullable2.GetValueOrDefault() + 1)
: ((int?) (nullable3 = null));
num2 = --num;
nullable = nullable2.HasValue
? new int?(nullable2.GetValueOrDefault() - --num)
: null;
Console.WriteLine("With Nullable<int> n = {0}", nullable);
他们或多或少相同,直到nullable
的作业。它运行--num
两次,导致它运行2 - -1
,结果为3。
对于像i = ~i
这样的表达式也是如此,但对于方法调用表达式却没有...
答案 1 :(得分:4)
这是一个非常有趣的问题,我可以看到编译器出现,不止一次地评估--
/ ++
语句。例如,以下内容:
n = ++n - new Nullable<int>(i++)
会导致n
成为0
(您期望的那样),但i
现在是3
(您期望2
)。但是,如果我这样做
n = ++n - new Nullable<int>(i);
然后我得到了预期的结果(n
= 1
和i
= 1
)
我只能假设这是以某种方式与new Nullable
调用相关联。我并不认为这是一个很大的问题,因为这可能不会被认为是你的日常代码,但是,在我看来,这似乎是编译器的一个错误。
答案 2 :(得分:-2)
这是最奇怪的,我试图追踪实际的代码' - '但我不能,但如果你这样做
n = 1;
i = 1;
n = ++n - new Nullable<int>(i--);
Console.WriteLine("With Nullable<int> n = {0}", n); //outputs n = 2
Console.ReadKey();
按预期输出。
编辑:全部揭晓:
http://msdn.microsoft.com/en-US/library/wc3z3k8c(v=vs.80).aspx
答案 3 :(得分:-3)
这是因为在这一行:
n = ++n - new Nullable<int>(--i);
我变成-1和2 - ( - 1)= 3;
它变为负1的原因是你正在创建一个初始化为0然后减去一个(i)的nulluable对象。
您可以在浏览器中将此代码作为* .cshtml文件运行:
@{
int? m = 1;
int i = 1;
m = ++m - --i;
//MessageBox.Show("Without Nullable<int> n = {0}", n); //outputs n = 2
int? n = 1;
i = 1;
n = ++n - new Nullable<int>(--i);
//MessageBox.Show("With Nullable<int> n = {0}", n); //outputs n = 3
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<h2>m = @m</h2>
<h2>n = @n</h2>
</body>
</html>