带有通用约束的C#重载

本文关键字:重载 约束 | 更新日期: 2023-09-27 18:00:36

为什么这两个方法不能有相同的名称?是因为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;
}

带有通用约束的C#重载

绝对正确。参见C#语言规范(版本5)的3.6节:

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

(我的重点)

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

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

和:

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


这能在C#的未来版本中实现吗?

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