You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 07:32:01