4

我一直在 C# 编译器中摸索它的“继承的实例化泛型类”的限制。

无论如何,这是我的测试用例:

class Program
{
    static void Main(string[] args)
    {
        var x = new InClass();
        Console.WriteLine(x.Test(10)); //prints foo
        Console.ReadLine();
    }
}
class BaseClass<Foo, Bar>
{
    public virtual Foo Test(Bar b)
    {
        return default(Foo);
    }
    public virtual string Test(int b)
    {
        return "foo"; ;
    }
}
class InClass : BaseClass<string, int>
{
    /*public override string Test(int b)
    {
        return "bar";
    }*/
}

我认为 InClass 的这个声明会引发编译器错误,因为它会产生Test歧义。这也使得非泛型Test无法在InClass. 请注意,我也注释掉了一些代码InClass。如果我取消注释该代码,我会收到编译器错误。

在 C# 规范中是否完全提到了这种行为,或者这是闻所未闻的边缘情况?

4

3 回答 3

7

我认为 InClass 的这个声明会引发编译器错误,因为它会使 Test 模棱两可。

没有。规范在第 7.5.3.6 节中明确指出了这种事情:

虽然声明的签名必须是唯一的,但类型参数的替换可能会导致相同的签名。在这种情况下,上述重载决议的平局规则将选择最具体的成员。

以下示例显示根据此规则有效和无效的重载。

(显然,示例如下。)

所以语言设计者已经考虑过了,但可能替代方案会更糟。(例如,InClass即使您不想调用Test,也无法创建类会很烦人。)

于 2012-08-23T20:29:20.513 回答
1

请参阅此相关问题:

为什么泛型类型约束不可继承/分层强制执行

Eric Lippert 对潜在影响进行了彻底的探索。

编译器不会强制执行继承的泛型类型,因为他们的开发团队认为这是一个不值得去的兔子洞。

于 2012-08-23T20:29:25.960 回答
0

我的猜测是带有签名的方法比在这种特殊情况下碰巧具有泛型类型的方法(int x)更适合参数。intBarint

于 2012-08-23T20:30:41.907 回答