当类型参数未知但实际上未被使用时,如何针对泛型类型进行模式匹配?

How do I do pattern matching against generic type when type parameter is unknown, but effectively not used?

我有一个 classes 的层次结构来模拟有区别的联合。其中一个 class 是一条记录:

private sealed record ErrorStrWithEnum<TEnum>(string Error, TEnum Enum) : Error
            where TEnum : struct, Enum

然后我有一个 Error 类型的对象,我想提取消息:

error switch
{
   ErrorStrWithEnum<_>(var message, _) => message
}

这显然行不通。即使 classes 支持协方差,我也无法与 ErrorStrWithEnum<object>(var message, _) 匹配,因为值类型不支持 cov-/contravariance。

替代方法是引入中介类型ErrorStrWithEnum(string Error, object Enum)但是会造成装箱

还有更优雅的选择吗?

您需要为消息或接口引入带有字符串的非通用记录并与之匹配:

private record ErrorWithStr(string Error) : Error;
private sealed record ErrorStrWithEnum<TEnum>(string Error, TEnum Enum) : ErrorWithStr(Error)
        where TEnum : struct, Enum;
error switch
{
   ErrorWithStr(var message) => message
}

private interface IHaveError {
    string Error { get; }
}
private sealed record ErrorStrWithEnum<TEnum>(string Error, TEnum Enum) : Error, IHaveError 
    where TEnum : struct, Enum
x switch
{
    IHaveError  err=> err.Error
}

记录可以实现接口,因此您可以将该字符串公开为接口 属性:

private interface IHasMessage {
    string Message { get; }
}

private sealed record ErrorStrWithEnum<TEnum>(string Message, TEnum Enum) 
    : Error, IHasMessage
    where TEnum : struct, Enum
{
    ...
}

那么你可以匹配IHasMessage:

error switch
{
   IHasMessage { Message: var message } => message
}