C# 为扩展方法错误生成CS1720警告(?)

C# 为扩展方法错误生成CS1720警告(?),c#,C#,考虑以下计划: 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(str

考虑以下计划:

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
    }
}
但是,C#编译器在第一个标记行上给出了CS1720警告:

警告CS1720:表达式将始终导致System.NullReferenceException,因为“string”的默认值为null


我的问题是:为什么编译器会建议出现NullReferenceException?
Extension()
的第一次调用相当于第二次调用,但第二次调用不会产生警告。这两个调用都应该是安全的,因为
这个字符串str
是一个参数,可以安全地为null,如第二行所示。我已经能够在3.5、4.0和4.5编译器上重现这一点,但在Mono 3.0.7上无法重现。

在第一种情况下,您是取消引用空对象,在第二种情况下,您是使用空参数调用方法

==更新==

让我再次声明,是的,这似乎不是一个合理的警告。我怀疑编译器发出了警告,因为它认为取消空对象的定义是“错误的”。该警告可能早于扩展方法功能


看看Roslyn是如何将其分解的,这会很有趣。

显然答案是肯定的,警告是不正确的。你已经很好地证明了这一点。(也许这就是它毕竟是一个警告的原因)


因为使用
null
值调用扩展方法并没有坏处。我猜编译器团队没有完成所有的工作来检查该方法是否调用了扩展方法。

这两行在功能上是相同的。是的,但我想编译器仍然认为这是对空对象的尊重。我想Roslyn可能会提供更多信息。对,这就是问题所在。为什么编译器会将其视为解引用?即使是聪明的编译器也没有那么聪明。我怀疑它有一个默认(对象)检查,然后是一个deref并发出警告。这只是一个bug。他们当时看起来并不急于修复它。你可以添加一个
#pragma warning disable 1720
(用一个很好的注释描述原因)。事实上,警告的实现可能早于扩展方法功能。
String is null
String is null