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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:40:01