代码之家  ›  专栏  ›  技术社区  ›  Richard Pawson

创建具有不同参数类型的C#函数列表

  •  1
  • Richard Pawson  · 技术社区  · 3 年前

    我希望能够创建多个 Func s每个都接受一个类型的实例并返回相同的类型,例如:

    Func<Foo, Foo>
    Func<Bar, Bar>
    

    然后将这些添加到 List (或者可能是 Dictionary ,按类型键入 函数 手柄)。

    然后给出任何实例 y (其类型未知 编译时 ),我想检索并调用 函数 这将适用于 y .

    我所要求的是可能的吗?

    1 回复  |  直到 3 年前
        1
  •  7
  •   Theraot    3 年前

    您可以创建一个代理词典。使用类型作为关键字。

    Dictionary<Type, Delegate> _dictionary = new();
    

    我们需要一种方法来添加委托:

    bool Add<T>(Func<T, T> func)
    {
        return _dictionary.TryAdd(typeof(T), func);
    }
    

    一个叫他们:

    static T DoIt<T>(T t)
    {
        if (_dictionary.TryGetValue(typeof(T), out var func))
        {
            return ((Func<T, T>)func).Invoke(t);
        }
       
        throw new NotImplementedException();
    }
    

    工作示例:

    using System;
    using System.Collections.Generic;
                        
    public class Program
    {
        private static Dictionary<Type, Delegate> _dictionary = new();
        
        public static void Main()
        {      
            Add<String>(InternalDoIt);
            Add<int>(InternalDoIt);
            DoIt("Hello World"); // Outputs "Hello World"
            DoIt(1); // Outputs "1"
            DoIt(DateTime.Now); // Throws NotImplementException
        }
        
        static bool Add<T>(Func<T, T> func)
        {
            return _dictionary.TryAdd(typeof(T), func);
        }
        
        static T DoIt<T>(T t)
        {
            if (_dictionary.TryGetValue(typeof(T), out var func))
            {
                return ((Func<T, T>)func).Invoke(t);
            }
            
            throw new NotImplementedException();
        }
        
        static string InternalDoIt(string str){
                Console.WriteLine(str);
                return str;
        }
        static int InternalDoIt(int i) {
                Console.WriteLine(i);
                return i;
        }
    }
    

    在回答这个问题的过程中,没有小狗或小猫死亡。

        2
  •  0
  •   Rand Random    3 年前

    你考虑过以下方法吗?

    using System;
                        
    public class Program
    {
        public static void Main()
        {
            DoIt("Hello World");
            DoIt(1);
            DoIt(DateTime.Now);
        }
        
        static dynamic DoIt(dynamic t)
        {
            return InternalDoIt(t);
        }
        
        static object InternalDoIt(object obj) => throw new NotImplementedException();
        static string InternalDoIt(string str){
                Console.WriteLine(str);
                return str;
        }
        static int InternalDoIt(int i) {
                Console.WriteLine(i);
                return i;
        }
    }
    

    https://dotnetfiddle.net/RoXK0M