带有泛型约束的 C# 重载

Pel*_*red 3 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;
}
Run Code Online (Sandbox Code Playgroud)

Dam*_*ver 6

完全正确。请参阅C# 语言规范(版本 5)的第 3.6 节:

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

(我的重点)

所以这两种方法的签名都是有效的:

GetValueOrNull<T1,T2>(IDictionary<T1,T2>,T1)
Run Code Online (Sandbox Code Playgroud)

和:

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


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

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