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

C#中泛型类型参数未知且未使用时如何进行模式匹配?

解决方案

你可以选择以下几种无装箱、低侵入的实现方案,按推荐优先级排序:

方案1:基类新增抽象属性(最简洁)

如果可以修改Error基类的定义,直接在基类加抽象的错误消息属性,所有子类统一实现:

internal abstract record Error
{
    public abstract string ErrorMessage { get; }
}

// 你的泛型record只需补充重写逻辑
private sealed record ErrorStrWithEnum<TEnum>(string Error, TEnum Enum) : Error
    where TEnum : struct, Enum
{
    public override string ErrorMessage => Error;
}

后续使用时不需要任何模式匹配,直接访问属性即可:

var message = error.ErrorMessage;

该方案完全无额外开销,代码逻辑最直观。

方案2:新增非泛型接口(零侵入基类)

如果不能修改Error基类,给泛型record实现一个非泛型的消息接口即可:

// 定义非泛型接口
internal interface IHasErrorMessage
{
    string Error { get; }
}

// 让泛型record实现接口
private sealed record ErrorStrWithEnum<TEnum>(string Error, TEnum Enum) : Error, IHasErrorMessage
    where TEnum : struct, Enum

匹配时直接判断接口类型:

var message = error switch
{
    IHasErrorMessage err => err.Error,
    // 其他Error子类的匹配分支
    _ => string.Empty
};

该方案同样无装箱、无运行时额外开销,不需要修改现有基类逻辑。

方案3:反射匹配(仅适用无法修改类定义的场景)

如果完全不能修改现有任何类的定义,可以用反射提取属性,仅适合非高频调用场景:

var message = error switch
{
    var e when e.GetType().IsGenericType 
        && e.GetType().GetGenericTypeDefinition() == typeof(ErrorStrWithEnum<>)
        => (string)e.GetType().GetProperty(nameof(Error)).GetValue(e),
    _ => string.Empty
};

该方案有反射开销,不建议在性能敏感路径使用。


内容的提问来源于stack exchange,提问作者Pavel Voronin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 07:45:06