将接口实现传递给泛型Method <t>(T args)(C#)时,获取实型

时间:2019-05-14 19:49:04

标签: c# generics interface

我有一个EventAggregator实现,可以区分事件类型并以该事件类型为参数调用所有已注册的回调,因此Publish-Method如下所示:

public void Publish<T>(T args) where T : IEvent
{
     if (callbacks != null)
     {
          var callbacksByEvent = callbacks.GetCallbacksByEventType(typeof(T));
          if (callbacksByEvent != null)
          {
               foreach (var callback in callbacksByEvent)
               {
                   if (callback is Action<T>)
                   {
                        Task.Run(() => ((Action<T>)callback)(args));
                   }
               }
          }
     }
}

IEvent只是事件类的空标记接口。当将诸如SomethingHappenedEvent : IEvent之类的硬编码实现传递到方法中时,它工作得很好,但是我想创建一个通知窗口,在该窗口中,可以将所有IEvent实现都分配给按钮“是”,“否”,“取消”,并且它们单击时将执行:

private IEvent CancelEvent;

private void Cancel()
{
     if (CancelEvent != null)
     {
         EventAggregator.Publish(CancelEvent);
     }
}

在此方案中,callbacks.GetCallbacksByEventType(typeof(T))返回NULL,因为TIEvent,但是回调方法已在实际的实现中注册: EventAggregator.Subscribe<SomethingHappenedEvent>(OnSomethingHappened)

如果将其更改为callbacks.GetCallbacksByEventType(args.GetType()),则会得到期望的回调列表,但如果声明为

if(callback is Action<T>) 

仍然返回false,因为T仍然是IEvent,并且方法不是Action<IEvent>,而是Action<SomethingHappenedEvent>

所以问题是:如何获得T成为我的SomethingHappenedEvent? 我可以使用.GetType()在运行时从类中获取实际的Type,所以应该可行吗?我在.NET Framework 4.5上。

我阅读了很多有关泛型和接口的Stackoverflow帖子,但找不到我想要的东西!你能帮忙吗?感谢您阅读所有这些:D

//编辑:抱歉,这是GetCallbacksByEventType方法的代码:


        internal List<Delegate> GetCallbacksByEventType(Type eventType)
        {
            List<Delegate> callbacks;
            lock (delegateTable)
            {
                if (!delegateTable.ContainsKey(eventType))
                {
                    return null;
                }

                List<WeakDelegate> weakReferences = delegateTable[eventType];

                callbacks = new List<Delegate>(weakReferences.Count);
                for (int i = weakReferences.Count - 1; i > -1; --i)
                {
                    WeakDelegate weakReference = weakReferences[i];
                    if (weakReference.IsAlive)
                    {
                        callbacks.Add(weakReference.GetDelegate());
                    }
                    else
                    {
                        weakReferences.RemoveAt(i);
                    }
                }

                if (weakReferences.Count == 0)
                {
                    delegateTable.Remove(eventType);
                }
            }
            return callbacks;
        }

和WeakReference类是:

internal sealed class WeakDelegate
{
    readonly Type DelegateType;
    readonly MethodInfo DelegateFunction;
    readonly WeakReference DelegateTarget;


        public Delegate GetDelegate()
        {
            object target = DelegateTarget.Target;
            if (target != null)
            {
                return Delegate.CreateDelegate(DelegateType, target, DelegateFunction);
            }
            return null;
        }
}

0 个答案:

没有答案