为什么下面的代码行不能创建一个编译器警告?
void Main()
{
throw new Exception();
throw new Exception();
}
在我看来,编译器应该告诉你的是,第二抛出异常无法达成。
为什么下面的代码行不能创建一个编译器警告?
void Main()
{
throw new Exception();
throw new Exception();
}
在我看来,编译器应该告诉你的是,第二抛出异常无法达成。
这显然是一个编译器缺陷,它被引入C#3.0 - 对周围我重构严重的可达性检查的时间。 这大概是我不好,对不起。
该缺陷是完全良性的; 基本上,我们只是忘了在警告记者的情况。 我们正确地生成的可达性信息; 正如其他人所指出的,我们正确地修剪出的代码生成之前无法访问的代码。
该错误无非是在警告发生器遗漏的情况多。 我们有一些棘手的代码在那里,确保我们当你的代码无法访问一些大节不报是数不胜数警告。 编译器有代码无条件的goto(“转到”,“破发”,“继续”),有条件的goto特别报告警告(“如果”,“而”等),的try-catch-finally程序(包括等价形式到的try-catch-最后,如锁和使用),块,返回(回收率和定期返程),局部声明,标号语句,开关和表达语句。
你看到的是名单上的“throw语句”? 我也不。 这是因为我们忘记它。
不便之处敬请原谅。 我会发一张纸条给QA,我们会尽快为这个修复到语言的未来版本。
感谢您将这一引起我的注意。
它会给人一种编译器警告/错误,但遗憾的是它没有。 但是,如果你看看IL代码只第一异常重视。 您可以登录到connect.microsoft.com,提高本的东西,你想看到的。
如果你ILDASM下面的代码
static void Main(string[] args)
{
Console.Write("Line 1");
throw new Exception();
throw new Exception();
Console.Write("Line 4");
}
您将获得本
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 18 (0x12)
.maxstack 8
IL_0000: nop
IL_0001: ldstr "Line 1"
IL_0006: call void [mscorlib]System.Console::Write(string)
IL_000b: nop
IL_000c: newobj instance void [mscorlib]System.Exception::.ctor()
IL_0011: throw
} // end of method Program::Main
后的第一个异常对象没有别的转换为IL。
此错误(如利珀特称之为以上)有一些奇怪的后果。 当然,这样的代码也没有给出编译时警告:
static int Main()
{
return 0;
throw new Exception("Can you reach me?");
}
如果你是有创意,你仍然可以使throw
声明诱导(无关)的警告。 在这种奇怪的例子中,代码生成,只是因为“绿色”不可达的警告:
static int Main()
{
return 0;
throw new Exception(((Func<string>)(() => { if (2 == 2) { return "yellow"; } return "green"; }))());
}
(代码只是从拉姆达创建委托实例并调用代表)。
但这个例子比较简单,似乎更糟糕:
static int Main()
{
int neverAssigned;
return 0;
throw new Exception(neverAssigned.ToString());
}
这最后的代码示例还编译没有警告! 有一个在“使用”没有问题neverAssigned
因为“使用”不可达。 但你也没有得到关于一个局部变量从未分配给(和从来没有“真正”读)的警告。 如此重复,没有警告可言,这似乎是非常错误的。
我不知道这种行为将在Visual C#中的未来版本是否会改变? 改变它会给人警告他们以前是没有的(这在我看来他们应得的)。
另外:此行为似乎与不变罗斯林为基础的的Visual Studio 2015年的C#6.0编译。