我有一个将通用委托存储到对象列表中的解决方案,但有没有办法将它们存储在类型列表中并避免转换? 我找不到办法,总是得到“找不到命名空间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);
}
}
答案 0 :(得分:0)
这是不可能的,但我喜欢这种方法作为解决方法:
首先创建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/