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

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

问题描述

考虑下面的类,

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

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

以上code是无效,将无法编译。现在考虑下面的code,

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);
}

以上code是有效的,编译好。它调用的美孚(诠释计数)

我的问题是,如果第一个是无效的,怎么能第二个是有效的?我知道类的美孚&LT; T&GT; 的是有效的,因为T和INT是不同的类型。但是,当它的使用方式的美孚&LT; INT&GT;富=新的Foo&LT; INT&GT;(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?

推荐答案

在正在设计C#2.0,并在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)是非法的声明泛型类,也可能会被一些建筑之下暧昧。 (这是绑定的规范正确说是规则)。所以你的美孚&LT; T&GT; 声明是非法的。

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)是非法的,构造一个产生歧义的方式,一个泛型类。声明美孚&LT; T&GT; 将是合法的,构建美孚&LT;双&GT; 将是合法的,但建设美孚&LT; INT方式&gt; 将是非法的。

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)使这一切合法,并使用重载的技巧,制定出通用或非泛型版本是否更好。 (这是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&LT;流&gt; 是模糊的?呸。规则#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。这意味着,有可能在理论上是转化为非法code,这是深深的不幸法律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:

<一个href=\"http://blogs.msdn.com/ericlippert/archive/2006/04/05/569085.aspx\">http://blogs.msdn.com/ericlippert/archive/2006/04/05/569085.aspx

<一个href=\"http://blogs.msdn.com/ericlippert/archive/2006/04/06/odious-ambiguous-overloads-part-two.aspx\">http://blogs.msdn.com/ericlippert/archive/2006/04/06/odious-ambiguous-overloads-part-two.aspx

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

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