使用泛型约束进行C#重载

时间:2014-04-29 08:21:20

标签: c# generics

为什么这两种方法不能有相同的名称?是因为C#编译器没有考虑重载的泛型类型约束吗?可以在将来的C#版本中完成吗?

public static TValue GetValueOrNull<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key)
            where TValue : class
{
    TValue value;
    if (dictionary.TryGetValue(key, out value))
        return value;
    return null;
}

public static TValue? GetValueOrNull<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key)
        where TValue : struct
{
    TValue value;
    if (dictionary.TryGetValue(key, out value))
        return value;
    return null;
}

1 个答案:

答案 0 :(得分:4)

绝对正确。请参阅C# Language Spec (version 5)

的第3.6节
  

方法的签名包括方法的名称,类型参数的数量以及每个形式参数的类型和种类(值,参考或输出),顺序从左到右。 出于这些目的,在形式参数类型中出现的方法的任何类型参数不是通过其名称来标识,而是通过方法的类型参数列表中的序号位置来标识方法的签名特别不包括返回类型,可以为最右边的参数指定的params修饰符,也不包括可选的类型参数约束。

(我的重点)

因此两种方法的签名都是有效的:

GetValueOrNull<T1,T2>(IDictionary<T1,T2>,T1)

  

重载方法允许类,结构或接口声明具有相同名称的多个方法,如果它们的签名在该类,结构或接口中是唯一的


  

可以在将来的C#版本中完成吗?

我怀疑它,除非或直到类型推断成为一个更容易解决的问题。类型推断可能已经花费了大量时间,因为编译器通常必须执行暴力方法。考虑到当前的机器,它必须同时考虑过载分辨率可能会非常昂贵。