泛型方法和方法重载 [英] Generic methods and method overloading

查看:172
本文介绍了泛型方法和方法重载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

方法重载允许我们定义具有相同的名称,但有不同的参数(因此具有相同名称但不同的签名),许多方法。

难道这两种方法重载?

  A级
{
    公共静态无效的MyMethod< T>(T设为myVal){}
    公共静态无效的MyMethod(INT设为myVal){}
}

编辑:

应该不会声明 A< INT> .MyMethod(敏); 抛出一个错误,因为构造类型 A< INT> 有两种方法具有相同的名称和相同的签名?


解决方案

  

是两种方法重载?



  

应该不会声明 A< INT> .MyMethod(敏); 抛出一个错误,因为构造类型 A< INT> 有两种方法具有相同的签名?


这个问题没有意义; A 是不是你已经宣布它泛型类型。也许你的意思是问:


  

如果声明 A.MyMethod(敏); 导致编译器将报告错误,因为有两个模糊的候选方法


没有。正如其他人所说,重载决议prefers在这种情况下,非通用版本。请参阅下面的更多细节。

或者,也许你的意思是问:


  

如果A型的声明是摆在首位非法的,因为在某些意义上,它有两个方法具有相同签名,的MyMethod 的MyMethod< INT>


没有。 A型是完全合法的。的通用元数是签名的一部分。因此,有没有这两种方法具有相同签名,因为第一个拥有通用的元数为零,第二个通用的元数之一。

或者,也许你的意思是问:

 类G< T>
{
    公共静态无效的M(T(T)){}
    公共静态无效M(INT T){}
}


  

泛型类型 G< T> 可以构造使得它有两种方法具有相同的签名。难道法律声明这样的类型?


是的,这是合法的声明这样的类型。它通常是一个的坏主意的,但它是合法的。

您可能会反驳,然后:


  

但我作为出版的479页上的Addison-Wesley出版社状态的C#2.0规范的副本的两个函数成员名称相同的声明...必须具备的参数类型,使得没有封闭构造类型可以有两个成员相同的名称和签名。的什么与了?


在C#2.0的设计原本是这样的计划。然而,随后的设计师意识到这个理想的模式将进行非法的:

 类℃下T>
{
    市民C(T(T)){...} //创建一个C< T>从一个给定Ť
    市民C(流s){...} //反序列化℃下T>从磁盘
}

和现在我们说对不起,哥们,因为你可以说 C<流> ,造成两个构造统一,全班是非法的。这将是不幸的。显然,这是不可能的,任何人都不会建造这件事与流作为类型参数!

不幸的是,规范来到preSS文本已更新为最终版本之前。 479页的规则是不是我们实现的。

继续摆姿势代表你的一些问题:


  

所以,如果你发生了什么 G< INT> .M(123),或在原来的例子,如果你调用 A.MyMethod (123)


当重载方案面临由于通用结构则一个是通用的结构被认为是少特定的比一个是天然的两种方法具有相同的签名。一个较具体的方法失去了一个更具体的方法。


  

那么,为什么它是一个糟糕的主意,如果重载工程?


的情况 A.MyMethod 是不是太糟糕;它通常是pretty容易明确地制定出该方法适用。但随着 G&LT情况; INT> .M(123)是差远了。 CLR的规则,使这种局面实现定义的行为,因此任何旧事都有可能发生。技术上,CLR可以拒绝证实构造型 G&LT方案; INT> 。或者,它可能会崩溃。事实上一点上,它什么都不做;它与恶劣的情况下最好就可以了。


  

有没有真正造成实现定义的这种结构类型的例子?


是的。请参阅以下文章的详细信息:

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

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

Method overloading allows us to define many methods with the same name but with a different set of parameters ( thus with the same name but different signature ).

Are these two methods overloaded?

class A
{
    public static void MyMethod<T>(T myVal) { }
    public static void MyMethod(int myVal) { }
}

EDIT:

Shouldn't statement A<int>.MyMethod(myInt); throw an error, since constructed type A<int> has two methods with the same name and same signature?

解决方案

Are the two methods overloaded?

Yes.

Shouldn't statement A<int>.MyMethod(myInt); throw an error, since constructed type A<int> has two methods with the same signature?

The question doesn't make sense; A is not a generic type as you have declared it. Perhaps you meant to ask:

Should the statement A.MyMethod(myInt); cause the compiler to report an error, since there are two ambiguous candidate methods?

No. As others have said, overload resolution prefers the non-generic version in this case. See below for more details.

Or perhaps you meant to ask:

Should the declaration of type A be illegal in the first place, since in some sense it has two methods with the same signature, MyMethod and MyMethod<int>?

No. The type A is perfectly legal. The generic arity is part of the signature. So there are not two methods with the same signature because the first has generic arity zero, the second has generic arity one.

Or perhaps you meant to ask:

class G<T> 
{
    public static void M(T t) {}
    public static void M(int t) {}
}

Generic type G<T> can be constructed such that it has two methods with the same signature. Is it legal to declare such a type?

Yes, it is legal to declare such a type. It is usually a bad idea, but it is legal.

You might then retort:

But my copy of the C# 2.0 specification as published by Addison-Wesley states on page 479 "Two function members declared with the same names ... must have have parameter types such that no closed constructed type could have two members with the same name and signature." What's up with that?

When C# 2.0 was originally designed that was the plan. However, then the designers realized that this desirable pattern would be made illegal:

class C<T> 
{
    public C(T t) { ... } // Create a C<T> from a given T
    public C(Stream s) { ... } // Deserialize a C<T> from disk
}

And now we say sorry buddy, because you could say C<Stream>, causing two constructors to unify, the whole class is illegal. That would be unfortunate. Obviously it is unlikely that anyone will ever construct this thing with Stream as the type parameter!

Unfortunately, the spec went to press before the text was updated to the final version. The rule on page 479 is not what we implemented.

Continuing to pose some more questions on your behalf:

So what happens if you call G<int>.M(123) or, in the original example, if you call A.MyMethod(123)?

When overload resolution is faced with two methods that have identical signatures due to generic construction then the one that is generic construction is considered to be "less specific" than the one that is "natural". A less specific method loses to a more specific method.

So why is it a bad idea, if overload resolution works?

The situation with A.MyMethod isn't too bad; it is usually pretty easy to unambiguously work out which method is intended. But the situation with G<int>.M(123) is far worse. The CLR rules make this sort of situation "implementation defined behaviour" and therefore any old thing can happen. Technically, the CLR could refuse to verify a program that constructs type G<int>. Or it could crash. In point of fact it does neither; it does the best it can with the bad situation.

Are there any examples of this sort of type construction causing truly implementation-defined behaviour?

Yes. See these articles for details:

http://blogs.msdn.com/b/ericlippert/archive/2006/04/05/odious-ambiguous-overloads-part-one.aspx

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

这篇关于泛型方法和方法重载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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