考虑以下计划:
static class Program
{
static void Extension(this string str)
{
if(str == null)
Console.WriteLine("String is null");
else
Console.WriteLine("String is not null");
}
static void Main(string[] args)
{
default(string).Extension(); // <--- warning
Extension(default(string)); // <--- no warning
}
}
输出符合预期:
String is null
String is null
但是,C#编译器在第一个标记行上发出CS1720警告:
警告CS1720:表达式总是会导致System.NullReferenceException,因为&#39; string&#39;的默认值为空
我的问题是:为什么编译器会建议会出现NullReferenceException?第一次调用Extension()
等同于第二次调用,但第二次调用不会产生警告。两个调用都应该是安全的,因为this string str
是一个参数,可以安全地为null,如第二行所示。我能够在3.5,4.0和4.5编译器上重现这一点,但不能在Mono 3.0.7上重现。
答案 0 :(得分:3)
显然答案是肯定的,警告是不正确的。你已经证明了这一点。 (可能这就是它毕竟是一个警告的原因)
作为discussed earlier调用带有null
值的扩展方法并不会造成任何损害。我想编译器团队没有通过所有麻烦来检查是否将方法称为扩展方法。
答案 1 :(得分:1)
在第一种情况下,您要取消引用一个空对象,在第二种情况下,您正在调用一个带有null参数的方法。
==更新==
让我重新陈述,是的,这似乎不是一个合理的警告。我怀疑编译器发出警告,因为它认为deref'ing null对象是“坏”。警告可能在扩展方法功能之前。
看看罗斯林如何分解它会很有趣。