如何优雅地根据泛型参数类型实现分支判断?
问题描述
我希望根据泛型参数的类型进行分支判断 我找到了一种可行且能通过测试的实现方式(*1)(编辑补充:该方式对string类型不生效,可查看@dbc的评论):
public static string HelpWithThis<T>(this DummyClass<T> _) => (T)default! switch // <- 我认为这是代码异味 { DateOnly => "This day", TimeOnly => "This hour", int or float => "This number", _ => "This", };
但我并不喜欢对default!进行类型转换的写法。
能否有人指导我如何用更优雅的语法重写这个函数?
测试
(*1)以下是完整的测试代码及复现步骤:
初始化项目命令
dotnet new xunit -o gentyp cd gentyp dotnet add package FluentAssertions
测试代码
// UnitTest1.cs using FluentAssertions; namespace gentyp; public class DummyClass<T>{} public static class DummyExtensions { public static string HelpWithThis<T>(this DummyClass<T> _) => (T)default! switch { DateOnly => "This day", TimeOnly => "This hour", int or float => "This number", _ => "This", }; } public class UnitTest1 { [Fact] public void Test1() => new DummyClass<int>() .HelpWithThis() .Should() .Be("This number"); }
解决方案
方案1:直接基于typeof(T)判断
避开默认值转换,直接针对泛型参数的类型做分支,逻辑更清晰:
public static string HelpWithThis<T>(this DummyClass<T> _) => typeof(T) switch { _ when typeof(T) == typeof(DateOnly) => "This day", _ when typeof(T) == typeof(TimeOnly) => "This hour", _ when typeof(T) == typeof(int) || typeof(T) == typeof(float) => "This number", _ => "This", };
方案2:使用default(T)做模式匹配
保留模式匹配风格,同时修复string类型不生效的问题:
public static string HelpWithThis<T>(this DummyClass<T> _) => default(T) switch { DateOnly => "This day", TimeOnly => "This hour", int or float => "This number", string => "This text", _ => "This", };
注:原写法中
(T)default!对引用类型(如string)会生成null,而模式匹配中string分支需要匹配非空值,改用default(T)后,default(string)就是null,结合C#的空兼容模式匹配逻辑,能正确命中string分支。
方案3:针对值类型用TypeCode简化(可选)
如果主要处理常见值类型,可借助Type.GetTypeCode减少重复的typeof判断:
public static string HelpWithThis<T>(this DummyClass<T> _) { var typeCode = Type.GetTypeCode(typeof(T)); return typeCode switch { TypeCode.Int32 or TypeCode.Single => "This number", _ when typeof(T) == typeof(DateOnly) => "This day", _ when typeof(T) == typeof(TimeOnly) => "This hour", _ => "This", }; }
此方案对
DateOnly、TimeOnly这类新增值类型需要额外判断,因为它们的TypeCode是Object。
内容的提问来源于stack exchange,提问作者dani herrera
相关产品推荐
相关产品推荐

