c#:为什么不使用方法签名解决这个不明确的枚举引用?

标签 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
    }
}

编译器提示 MyEnum 在对 Frobble() 的调用中是一个不明确的引用。由于调用的方法没有歧义,因此可能希望编译器根据方法签名解析类型引用。为什么不呢?

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

最佳答案

保罗是对的。在 C# 中的大多数情况下,我们“从内到外”进行推理。

there is no ambiguity in what method is being called,

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

恰好只包含一个方法的方法组在这方面并不特殊。在重载决议成功之前,我们仍然需要有好的论据。

在某些情况下,我们会“从外到内”进行推理,即在对 lambda 进行类型分析时。这样做会使重载决议算法变得极其复杂,并给编译器一个问题来解决,在坏的情况下至少是 NP-HARD。但在大多数情况下,我们希望避免这种复杂性和费用; 通过先于 parent 分析子表达式来分析表达式,而不是相反。

更一般地说:C# 不是一种“当程序不明确时使用试探法来猜测程序员可能的意思”的语言。它是一种“通知开发人员他们的程序不清楚并且可能损坏”的语言。旨在尝试解决歧义情况的语言部分——如重载解析或方法类型推断或隐式类型数组——经过精心设计,以便算法具有明确的规则,将版本控制和其他现实世界的方面考虑在内.一旦程序的一部分不明确,就立即退出是我们实现此设计目标的一种方式。

如果您更喜欢尝试弄清楚您的意思的更“宽容”的语言,VB 或 JScript 可能更适合您。它们更像是“按我的意思去做,而不是按我说的去做”的语言。

关于c#:为什么不使用方法签名解决这个不明确的枚举引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7128818/

相关文章:

node.js - 如何将特殊字符放入 apollo graphQL 服务器的枚举值中?

C++ 异常处理和枚举作用域

javascript - 使用 jQuery 命名属性的最佳模式

c++ - 有没有办法让 Visual Studio 停止缩进命名空间?

c# - 如何将 PDF 从 Web API 发送到 MVC 应用程序以供直接下载

c# - 如何通过 COM 互操作将 VBA 变量数组数据类型传递到 C# 方法中

c# - 实现递归哈希算法

c# - 无法将类型为 'Newtonsoft.Json.Linq.JObject' 的对象转换为类型 'System.Collections.Generic.Dictionary` 2[System.String,System.Object]'

swift - 具有相同案例名称且具有不同类型关联值的枚举

c++ - 使用 GMock 的具有命名空间的模拟方法