gpt4 book ai didi

c# - 通用委托(delegate)列表(例如 System.Converter)

转载 作者:行者123 更新时间:2023-12-04 22:54:19 30 4
gpt4 key购买 nike

是否可以创建通用代表列表,例如 System.Converter<TInput, TOutput> ?

在 java 中可能是 List<Converter<?,?>> ,但是使用 Java 的类型删除不是很有用。似乎在 C# 中应该可以在从列表中检索后查询泛型类型并使用获得的实例来执行所需的转换。

详细说明问题:
我以用户提供的格式提供了用户提供的数据,我在编译时对此一无所知。当然,我的程序中的算法知道如何使用它自己的特定数据类型。目标是拥有 Java 的 List<Converter<?,?>> 的等价物。在哪里可以安装转换器(由我或用户)并由程序自动查询以查看用户的数据是否可以转换为算法所需的格式。

最佳答案

这是非常初级的,只是为了展示基本概念。

它有:

  • 以输入和输出类型的 2 元组为键的字典以保存转换器实例。
  • 一个 Register用于注册转换器的方法。注册同一对类型会覆盖以前注册的转换器。您可以轻松地将其更改为无操作或异常。
  • 一个 Convert调用已注册转换器的方法。创建 TryConvert 非常简单。如果你需要它的方法。

  • public static class ConverterContainer
    {
    private static readonly Dictionary<(Type, Type), Delegate> _converters = new Dictionary<(Type, Type), Delegate>();

    public static void Register<TInput, TOutput>(Func<TInput, TOutput> converter)
    {
    if (converter is null)
    throw new ArgumentNullException(nameof(converter));

    _converters[(typeof(TInput), typeof(TOutput))] = converter;
    }

    public static TOutput Convert<TInput, TOutput>(TInput input)
    {
    if (_converters.TryGetValue((typeof(TInput), typeof(TOutput)), out var del))
    {
    Func<TInput, TOutput> converter = (Func<TInput, TOutput>)del;

    return converter(input);
    }

    throw new InvalidOperationException("Converter not registered.");
    }
    }

    它没有什么:
  • 线程安全。这留给认真的实现者作为练习。
  • 可能还有其他我没有花时间考虑的事情。

  • 如何使用它:

    在您的应用程序启动时,注册转换器,例如为依赖注入(inject)注册服务。

    ConverterContainer.Register<long, int>(l => (int)l);
    // ... etc.

    并且无论您想在注册的输入/输出类型对之间执行转换:
    int x = ConverterContainer.Convert<long, int>(1000L)

    不幸的是,您必须在此处指定两个类型参数。

    来自 OP 的补充:

    为了不必指定输入参数类型(这是拥有可用转换的动态列表的一种点),请在示例 ConverterContainer 中使用以下附加方法上面(正如@madreflection 在自己的评论中所建议的那样):
    public static TOutput Convert<TOutput>(object toConvert) {
    if (toConvert is null)
    throw new ArgumentNullException(nameof(toConvert));

    if (Converters.TryGetValue((toConvert.GetType(), typeof(TOutput)), out Delegate conv)) {
    object o = conv.DynamicInvoke(toConvert);
    return (TOutput) o;
    }

    throw new InvalidOperationException($"Converter not registered for types: {toConvert.GetType().Name} -> {typeof(TOutput).Name}");
    }

    您现在可以随意输入 object实例并查看是否可以转换为所需的类型。

    关于c# - 通用委托(delegate)列表(例如 System.Converter<TInput, TOutput>),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59369698/

    30 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com