如何在C#中定义Type到对应输入类型函数的字典?
解决Dictionary<Type, Func<T, string>>的编译错误问题
嘿,这个问题我之前也碰到过!咱们先拆解下为啥代码编译不过:你定义的Dictionary<Type, Func<T, string>>里的T是个未声明的泛型参数,编译器根本不知道这个T指的是什么类型。毕竟字典里要存的是不同输入类型的Func(string、float、bool),每个Func的输入类型都不一样,没法用一个统一的T来约束所有条目。
下面给你两种可行的解决方案,按需选择:
方案1:用Func<object, string>替代泛型Func(简单直接)
把字典的value类型改成接受object输入的Func,然后在每个委托里做类型转换,这样就能兼容所有类型了:
var stringifiers = new Dictionary<Type, Func<object, string>> { { typeof(string), s => (string)s }, { typeof(float), f => ((float)f).ToString() }, { typeof(bool), b => ((bool)b).ToString() } };
使用的时候和你原来的写法完全一致:
// 假设bar是某个变量 string result = stringifiers[bar.GetType()](bar);
这个方案的好处是简单直接,不需要额外封装;但要注意,调用前最好先判断stringifiers.ContainsKey(bar.GetType()),避免传入未注册类型时抛出KeyNotFoundException。
方案2:封装泛型注册/调用方法(类型更安全)
如果想要更类型安全的实现,避免显式转换和潜在的类型错误,可以封装一个类来处理注册和调用:
public class StringifierRegistry { private readonly Dictionary<Type, Delegate> _stringifiers = new Dictionary<Type, Delegate>(); // 注册对应类型的转换方法 public void Register<T>(Func<T, string> stringifier) { _stringifiers[typeof(T)] = stringifier; } // 执行转换 public string Stringify<T>(T value) { if (_stringifiers.TryGetValue(typeof(T), out var @delegate) && @delegate is Func<T, string> stringifier) { return stringifier(value); } throw new NotSupportedException($"没有为类型 {typeof(T)} 注册转换方法"); } }
使用方式如下:
var registry = new StringifierRegistry(); registry.Register<string>(s => s); registry.Register<float>(f => f.ToString("F2")); // 还可以自定义格式 registry.Register<bool>(b => b ? "是" : "否"); // 调用时编译器会自动推断T的类型 string result1 = registry.Stringify("Hello"); string result2 = registry.Stringify(3.14f); string result3 = registry.Stringify(true);
这种方案的优势在于类型安全,编译时就能检查类型匹配,而且可以更灵活地扩展不同类型的转换逻辑。
内容的提问来源于stack exchange,提问作者MichaelB
相关产品推荐
相关产品推荐

