nan*_*nan 10 c# generics overloading
我正在使用在泛型类中包含以下重载方法的代码:
public class A<T>
{
    public void Process(T item) { /*impl*/ }
    public void Process(string item) { /*impl*/ }
}
当参数化类时,string我是否失去了使用泛型参数调用版本的可能性?
var a = new A<string>();
a.Process(""); //Always calls the non-generic Process(string)
Ken*_*rey 14
特定类型优先于泛型类型.
例如,这是我在LINQPad中测试的内容.
void Main()
{
    new A<string>().Process("Hello");
}
public class A<T>
{
    public void Process(T item) { Console.WriteLine("T"); }
    public void Process(string item) { Console.WriteLine("string"); }
}
// Output: string
如果您在隐藏通用方法时遇到问题,那么您需要重新考虑一些事情.通过重载具有特定类型的泛型方法,您实际上是在说"如果需要,请使用泛型重载,但如果可以,请使用特定版本,因为它应该知道什么是最好的. "
是.这在C#规范第7.5.3节"重载解析"中有记录.
从7.5.3.6开始:
"虽然声明的签名必须是唯一的,但是类型参数的替换可能会产生相同的签名.在这种情况下,上面的重载决策的打破平局规则将选择最具体的成员."
在那里给出的例子表明,在下面的情况下,重载分辨率G<int>.F1将选择非泛型
class G1<U>
{
    int F1(U u);
    int F1(int i);
}
这里适用的打破平局规则在7.5.3.2"更好的功能成员"中概述:
如果参数类型序列{P1,P2,...,PN}和{Q1,Q2,...,QN}是等效的(即每个Pi具有到相应Qi的标识转换),则应用以下打破平局规则,按顺序,确定更好的功能成员.
我刚刚发现了一种方法,但它有点眼花缭乱.由于泛型和重载在构建时得到解决,因此您可以定义泛型方法:
public static CallerClass
{
    public static CallGenericOverload<T>(GenericClass<T> cls, T val)
    {
        return cls.ProblemOverload(val); 
    }   
    //We can also make an extension method. 
    //We don't have to of course, it's just more comfortable this way.
    public static CallGenericOverloadExtension<T>(this GenericClass<T> cls, T val)
    {
        return cls.ProblemOverload(val);
    }
}
public GenericClass<T>
{
     public string ProblemOverload(T val)
     {
         return "ProblemOverload(T val)";
     }
     public string ProblemOverload(string val)
     {
         return "ProblemOverload(string val)";
     }
}
现在,如果我们执行以下操作:
var genClass = new GenericClass<string>();
Console.WriteLine(genClass.ProblemOverload("")); //output: ProblemOverload(string val)
Console.WriteLine(CallerClass.CallGenericOverload(genClass, "")); //output: ProblemOverload(T val)
Console.WriteLine(genClass.CallGenericOverloadExtension("")); //output: ProblemOverload(T val)
如果定义泛型类而不是泛型方法,则可以使用类似的技巧.重要的是,您传输的参数ProblemOverload需要是类型T而不是string调用中的类型.毕竟,该方法CallGenericOverload知道它正T处于构建时,因此它将绑定到接受该参数的重载.它实际上会string在运行时获得并不重要.
| 归档时间: | 
 | 
| 查看次数: | 455 次 | 
| 最近记录: |