能否在C#运算符重载中使用泛型类型参数?
泛型类型间+运算符拼接的实现方案
C#编译器不允许在运算符重载方法上单独声明无关联的泛型参数(即你代码中运算符后的<R, S>),核心原因是编译器无法推断这些未绑定的泛型类型。以下是几种可行的实现思路:
方案一:利用类型推断定义运算符
如果拼接后的结果类型S能从输入的T和R直接推导(比如是两者的组合类型),可以直接在运算符中使用参数的泛型参数,无需额外声明:
public class Query<T> { public T Value { get; } public Query(T value) => Value = value; // 拼接后返回包含T和R的元组类型Query public static Query<(T, R)> operator +(Query<T> left, SomeOtherObject<R> right) { return new Query<(T, R)>((left.Value, right.Value)); } } public class SomeOtherObject<R> { public R Value { get; } public SomeOtherObject(R value) => Value = value; }
若需要自定义组合类型,只需替换返回类型为对应的泛型类即可:
// 自定义组合类型 public class Combined<T1, T2> { public T1 Part1 { get; } public T2 Part2 { get; } public Combined(T1 part1, T2 part2) => (Part1, Part2) = (part1, part2); } // 修改运算符返回类型 public static Query<Combined<T, R>> operator +(Query<T> left, SomeOtherObject<R> right) { return new Query<Combined<T, R>>(new Combined<T, R>(left.Value, right.Value)); }
方案二:通过泛型约束关联类型
如果S需要满足特定转换或组合规则,可以通过接口约束将T、R和S关联,让编译器能推断泛型参数:
// 定义转换与组合接口 public interface IConvertTo<out TResult> { TResult Convert(); } public interface IAppendWith<in TOther, out TResult> { TResult Append(TOther other); } public class Query<T> { public T Value { get; } public Query(T value) => Value = value; // 通过约束让编译器推断R和S public static Query<S> operator +<R, S>(Query<T> query, SomeOtherObject<R> other) where R : IConvertTo<S> where T : IAppendWith<S, S> { S converted = other.Convert(); S combined = query.Value.Append(converted); return new Query<S>(combined); } } // 实现示例 public class SomeOtherObject<R> : IConvertTo<string> { public R Value { get; } public SomeOtherObject(R value) => Value = value; public string Convert() => Value.ToString(); } public class TextQuery : Query<string>, IAppendWith<string, string> { public TextQuery(string value) : base(value) { } public string Append(string other) => Value + other; }
方案三:改用静态方法(灵活泛型)
如果以上方案仍不满足需求,可以放弃运算符重载,改用命名静态方法,这样能自由声明泛型参数:
public class Query<T> { public static Query<S> Combine<R, S>(Query<T> query, SomeOtherObject<R> other) where R : IConvertTo<S> where T : IAppendWith<S, S> { S converted = other.Convert(); S combined = query.Value.Append(converted); return new Query<S>(combined); } }
调用时可依赖类型推断简化写法:Query.Combine(query, other)。
内容的提问来源于stack exchange,提问作者Adam
相关产品推荐
相关产品推荐

