【问题标题】:Can I store a generic method in a list?我可以将泛型方法存储在列表中吗?
【发布时间】:2018-05-09 19:11:10
【问题描述】:

我有一个将通用委托存储到对象列表中的解决方案,但是有没有办法将它们存储在类型列表中并避免强制转换? 我找不到任何办法,而且总是出现“找不到命名空间 T”之类的错误。

class TestClass {
    public delegate void dEvent<T>(object sender, T value);

    // is it possible to store the generic delegate directly ?
    // List<dEvent<T>> eventlist = new List<dEvent<T>>();

    List<object> objLst = new List<object>();

    public void Subscribe<T> (dEvent<T> ev){
        if (objLst.Contains(ev) == false)
            objLst.Add(ev);
    }

    public void InvokeAll<T>(object sender, T value) {
        foreach (var d in objLst.Where(o => (o as dEvent<T>) != null)) {
            (d as dEvent<T>).Invoke(sender, value);
        }
    }

    static public void StringSubscriber(object sender, string value) {
        Debug.WriteLine(value);
    }
    static public void IntSubscriber(object sender, int value) {
        Debug.WriteLine(value);
    }

    static public void RunTest() {
        TestClass testClass = new TestClass();
        testClass.Subscribe<string>(StringSubscriber);
        testClass.Subscribe<int>(IntSubscriber);
        testClass.InvokeAll<string>(testClass, "Hello");
        testClass.InvokeAll<string>(null, "World");
        testClass.InvokeAll<int>(testClass, 4);
        testClass.InvokeAll<int>(null, 2);
    }       
}

【问题讨论】:

    标签: .net list generics


    【解决方案1】:

    这是不可能的,但我喜欢这种方法作为一种解决方法:

    首先创建 2 个可重用的辅助类:

    public abstract class DelegateDef
    {
        public abstract Type Type { get; }
    }
    
    public class TypedDelegateDef<T> : DelegateDef
    {
        private T deleg;
        public T Deleg
        {
            get
            {
                return deleg;
            }
            set
            {
                deleg = value;
            }
        }
        public override Type Type
        {
            get
            {
                return typeof(T);
            }
        }        
    }
    

    那么它们可以这样使用:

    class TestClass
    {
        public delegate void dEvent<T>(object sender, T value);
    
        public List<DelegateDef> DelegList = new List<DelegateDef>();
    
        public void InvokeAll<T>(object sender, T value)
        {
            var list = DelegList.Where(o => (o.Type == typeof(dEvent<T>))).ToList();
            foreach (var d in list)
            {
                TypedDelegateDef<dEvent<T>> s = ((TypedDelegateDef<dEvent<T>>)d);
                ((dEvent<T>)s.Deleg).Invoke(sender, value);
            }
        }
    
        static public void StringSubscriber(object sender, string value)
        {
            Debug.WriteLine(value);
        }
        static public void IntSubscriber(object sender, int value)
        {
            Debug.WriteLine(value);
        }
    
        static public void RunTest()
        {
            TestClass testClass = new TestClass();
            testClass.DelegList.Add(new TypedDelegateDef<dEvent<string>>() {Deleg = StringSubscriber });
            testClass.DelegList.Add(new TypedDelegateDef<dEvent<int>>() { Deleg = IntSubscriber });
            testClass.InvokeAll<string>(testClass, "Hello");
            testClass.InvokeAll<string>(null, "World");
            testClass.InvokeAll<int>(testClass, 4);
            testClass.InvokeAll<int>(null, 2);
        }
    }
    

    解决方案基于: https://www.roelvanlisdonk.nl/2010/08/31/how-to-mix-generic-classes-in-a-generic-list-in-c/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-07-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-11
      • 2011-08-21
      • 1970-01-01
      相关资源
      最近更新 更多