当T1与T2类型相同时,如何让编译器区分两个Partial泛型方法?
解决T1与T2类型相同时Partial泛型方法的编译器歧义问题
当typeof(T1) == typeof(T2)时,你提供的两个Partial泛型方法会因为签名完全一致(泛型参数实例化后,参数类型和返回值类型均相同),导致编译器无法自动区分,产生重载歧义。以下是几种可行的解决方法:
方法1:使用命名参数
调用方法时明确指定参数名称arg1或arg2,编译器会根据参数名匹配对应的重载:
Action<int, int> add = (x, y) => Console.WriteLine(x + y); // 绑定第一个参数 var addFive = add.Partial(arg1: 5); addFive(3); // 输出 8 // 绑定第二个参数 var addToFive = add.Partial(arg2: 5); addToFive(3); // 输出 8
方法2:重命名方法消除歧义
直接给两个方法赋予不同的名称,从根源避免重载冲突,这也是最直观的方案:
public static Action<T2> PartialFirst<T1, T2>(this Action<T1, T2> action, T1 arg1) => arg2 => action(arg1, arg2); public static Action<T1> PartialSecond<T1, T2>(this Action<T1, T2> action, T2 arg2) => arg1 => action(arg1, arg2);
调用时直接使用明确的方法名:
var addFive = add.PartialFirst(5); var addToFive = add.PartialSecond(5);
方法3:用标记类型包装参数
给其中一个方法的参数添加标记性包装类型,让参数类型产生差异,帮助编译器区分重载:
// 定义用于标记第一个参数的结构体 public struct FirstArgument<T> { public T Value; } // 修改第一个Partial方法,接收包装后的参数 public static Action<T2> Partial<T1, T2>(this Action<T1, T2> action, FirstArgument<T1> arg1) => arg2 => action(arg1.Value, arg2); // 第二个方法保持原有定义 public static Action<T1> Partial<T1, T2>(this Action<T1, T2> action, T2 arg2) => arg1 => action(arg1, arg2);
调用时通过包装类型区分:
var addFive = add.Partial(new FirstArgument<int> { Value = 5 }); var addToFive = add.Partial(5);
需要注意的是,显式指定泛型参数无法解决此问题——当T1和T2类型相同时,两个方法实例化后的签名完全一致,编译器依然无法区分。
内容的提问来源于stack exchange,提问作者Matheus Leão
相关产品推荐
相关产品推荐

