c#:为什么不使用方法签名解析这个模糊的枚举引用?

Odr*_*ade 9 c# enums namespaces

请考虑以下代码:

namespace ConsoleApplication
{
    using NamespaceOne;
    using NamespaceTwo;

    class Program
    {
        static void Main(string[] args)
        {
            // Compilation error.  MyEnum is an ambiguous reference
            MethodNamespace.MethodClass.Frobble(MyEnum.foo);
        }
    }
}

namespace MethodNamespace
{
    public static class MethodClass
    {
        public static void Frobble(NamespaceOne.MyEnum val)
        {
            System.Console.WriteLine("Frobbled a " + val.ToString());
        }   
    }
}

namespace NamespaceOne
{
    public enum MyEnum
    {
        foo, bar, bat, baz
    }
}

namespace NamespaceTwo
{
    public enum MyEnum
    {
        foo, bar, bat, baz
    }
}
Run Code Online (Sandbox Code Playgroud)

编译器抱怨MyEnum在调用Frobble()时是一个模糊的引用.由于调用的方法没有歧义,因此可能希望编译器根据方法签名解析类型引用.为什么不呢?

请注意,我并不是说编译器应该这样做.我相信它有一个非常好的理由.我只想知道这是什么原因.

Eri*_*ert 14

保罗是对的.在C#的大多数情况下,我们推理"从内到外".

调用什么方法没有歧义,

对你来说明确无误与编译器无关.重载解析的任务是确定方法组是否Frobble可以解析为给定已知参数的特定方法.如果我们无法确定参数类型是什么,那么我们甚至不会尝试进行重载解析.

恰好恰好只包含一种方法的方法组在这方面并不特别.在重载解析成功之前,我们仍然必须有好的参数.

有些情况我们从"从外到内"推理,即在进行lambda的类型分析时.这样做会使重载决策算法极其复杂,并且给编译器一个问题,即在坏情况下至少是NP-HARD.但在大多数情况下,我们希望避免这种复杂性和费用; 通过分析父母之前的子子表达来分析表达式,而不是相反.

更一般地说:C#不是"当程序不明确时使用启发式来猜测程序员可能意味着什么"的语言.它是"告知开发人员他们的程序不清楚且可能已损坏"的语言.设计用于尝试解决模糊情况的语言部分(如重载解析或方法类型推断或隐式类型数组)经过精心设计,因此算法具有明确的规则,可将版本控制和其他现实世界方面考虑在内.一旦程序的一部分含糊不清就挽救了我们实现这一设计目标的一种方式.

如果你更喜欢试图找出你的意思的更"宽容"的语言,VB或JScript可能是更好的语言.他们更"做我意味着不是我所说的"语言.

  • 当所有人必须做的是链接到你的一篇很棒的博客文章时,很容易正确:) (5认同)

Pau*_*tum 6

我相信它,因为C#编译器通常不会回溯.