当两个重载具有相同的签名时调用构造器重载 [英] Calling constructor overload when both overload have same signature

查看:156
本文介绍了当两个重载具有相同的签名时调用构造器重载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑下面的类,

class Foo
{
    public Foo(int count)
    {
        /* .. */
    }

    public Foo(int count)
    {
        /* .. */
    }
}

上述代码无效,无法编译。现在考虑下面的代码,

Above code is invalid and won't compile. Now consider the following code,

class Foo<T>
{
    public Foo(int count)
    {
        /* .. */
    }

    public Foo(T t)
    {
        /* .. */
    }
}

static void Main(string[] args)
{
    Foo<int> foo = new Foo<int>(1);
}

上述代码有效且编译良好。它调用 Foo(int count)

Above code is valid and compiles well. It calls Foo(int count).

我的问题是,如果第一个无效,我知道类 Foo< T> 是有效的,因为T和int是不同的类型。但是当它像 Foo< int> foo = new Foo< int>(1),T是整数类型,两个构造函数都有相同的签名权限?为什么编译器不显示错误而不是选择重载来执行?

My question is, if the first one is invalid, how can the second one be valid? I know class Foo<T> is valid because T and int are different types. But when it is used like Foo<int> foo = new Foo<int>(1), T is getting integer type and both constructor will have same signature right? Why don't compiler show error rather than choosing an overload to execute?

推荐答案

正在设计CLR中的通用型系统。这么热,事实上,A-W发布的绑定C#2.0规范实际上有错规则!有四种可能性:

Your question was hotly debated when C# 2.0 and the generic type system in the CLR were being designed. So hotly, in fact, that the "bound" C# 2.0 specification published by A-W actually has the wrong rule in it! There are four possibilities:

1)在SOME构造下声明一个可能不明确的泛型类是非法的。因此,你的 Foo< T> 声明将是非法的。

1) Make it illegal to declare a generic class that could POSSIBLY be ambiguous under SOME construction. (This is what the bound spec incorrectly says is the rule.) So your Foo<T> declaration would be illegal.

2)以创建歧义的方式构造一个泛型类是非法的。声明 Foo< T> 将是合法的,构造 Foo c> Foo 将是非法的。

2) Make it illegal to construct a generic class in a manner which creates an ambiguity. declaring Foo<T> would be legal, constructing Foo<double> would be legal, but constructing Foo<int> would be illegal.

3)使它一切合法,并使用重载解析技巧, nongeneric版本更好。 (这是C#实际上做的。)

3) Make it all legal and use overload resolution tricks to work out whether the generic or nongeneric version is better. (This is what C# actually does.)

4)做其他我没有想到的事情。

4) Do something else I haven't thought of.

规则#1是一个坏主意,因为它使一些非常常见和无害的情况不可能。考虑例如:

Rule #1 is a bad idea because it makes some very common and harmless scenarios impossible. Consider for example:

class C<T>
{
  public C(T t) { ... } // construct a C that wraps a T
  public C(Stream state) { ... } // construct a C based on some serialized state from disk
}

您希望这是非法的只是因为 C< Stream> 是不明确的吗? Yuck。规则#1是一个坏主意,所以我们报废。

You want that to be illegal just because C<Stream> is ambiguous? Yuck. Rule #1 is a bad idea, so we scrapped it.

不幸的是,它不是那么简单。 IIRC CLI规则说,允许实现拒绝作为实际上导致签名模糊的非法构造。也就是说,CLI规则类似于规则#2,而C#实际上实现规则#3。这意味着理论上可以合法的C#程序转换为非法代码,这是非常不幸的。

Unfortunately, it is not as simple as that. IIRC the CLI rules say that an implementation is allowed to reject as illegal constructions that actually do cause signature ambiguities. That is, the CLI rules are something like Rule #2, whereas C# actually implements Rule #3. Which means that there could in theory be legal C# programs that translate into illegal code, which is deeply unfortunate.

有关这些种类的歧义如何使我们的生活的一些更多的想法可悲的是,这里是我写的关于这个主题的几篇文章:

For some more thoughts on how these sorts of ambiguities make our lives wretched, here are a couple of articles I wrote on the subject:

http://blogs.msdn.com/ericlippert/archive/2006/04/05/569085.aspx

http://blogs.msdn.com/ericlippert/archive/2006/04/06/odious-ambiguous-overloads-part-two.aspx

这篇关于当两个重载具有相同的签名时调用构造器重载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆