如何使用模式匹配开关重写此方法?
internal ResultType Fetch<ResultType>(string field)
{
var type = typeof(ResultType);
object xx = type switch
{
_ when type == typeof(DateTime) => FetchDateTime(field),
_ when type == typeof(DateOnly) => FetchDateOnly(field),
_ when type == typeof(bool) => FetchBool(field),
_ when type == typeof(decimal) => FetchDecimal(field),
_ when type == typeof(string) => FetchString(field),
_ when type == typeof(int) => FetchInt(field),
_ => throw new NotImplementedException($"this[field: {field}]")
};
if (xx is ResultType rt) return rt;
return default(ResultType)!;
}
最佳答案
作为答案发布,因为代码太长,无法发表评论。
您当然可以提高效率(忽略长度方面)。 JIT 识别模式 if (type == typeof(DateTime))
等,并将发出仅保留给定 ResultType
方法的相关部分的代码。
例如,当 ResultType
为 DateTime
时,您的代码会产生以下结果:
C.Fetch[[System.DateTime, System.Private.CoreLib]](System.String)
L0000: push ebp
L0001: mov ebp, esp
L0003: push esi
L0004: sub esp, 8
L0007: mov esi, edx
L0009: mov ecx, 0x6e099a4
L000e: call 0x060a300c
L0013: lea edx, [eax+4]
L0016: xor ecx, ecx
L0018: mov [edx], ecx
L001a: mov [edx+4], ecx
L001d: mov edx, eax
L001f: test edx, edx
L0021: je short L002b
L0023: cmp dword ptr [edx], 0x6e099a4
L0029: je short L003a
L002b: xor eax, eax
L002d: mov [esi], eax
L002f: mov [esi+4], eax
L0032: lea esp, [ebp-4]
L0035: pop esi
L0036: pop ebp
L0037: ret 4
L003a: add eax, 4
L003d: mov edx, [eax]
L003f: mov eax, [eax+4]
L0042: mov [ebp-0xc], edx
L0045: mov [ebp-8], eax
L0048: mov eax, esi
L004a: mov edx, [ebp-0xc]
L004d: mov [eax], edx
L004f: mov edx, [ebp-8]
L0052: mov [eax+4], edx
L0055: lea esp, [ebp-4]
L0058: pop esi
L0059: pop ebp
L005a: ret 4
但是代码:
internal ResultType Fetch2<ResultType>(string field)
{
var type = typeof(ResultType);
if (type == typeof(DateTime))
{
return (ResultType)(object)FetchDateTime(field);
}
if (type == typeof(DateOnly))
{
return (ResultType)(object)FetchDateOnly(field);
}
throw new NotImplementedException($"this[field: {field}]");
}
结果:
C.Fetch2[[System.DateTime, System.Private.CoreLib]](System.String)
L0000: push ebp
L0001: mov ebp, esp
L0003: xor eax, eax
L0005: mov [edx], eax
L0007: mov [edx+4], eax
L000a: pop ebp
L000b: ret 4
这是运行时使用的模式。
关于使用模板化类型的 C# 模式匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76818244/