订阅动态类型列表

时间:2015-03-14 15:34:07

标签: c# generics types

我在程序中使用Messenger,使用订阅和发布方法。 我想订阅一个特定对象的消息类型列表(实现接口" IMessage")。 所以,我有一个方法订阅。 看起来应该是这样的:

subscribe(List<T> listMessagesTypes)
{
     foreach(IMessage messageType in listMessagesTypes)
        _messenger.subscribe<messageType>(doAction);
}

当然,这不起作用

  • 我无法定义列表应仅包含实现IMessage接口的类型

  • messageType是一个对象,而不是一个类型。我的代码语法错误!

有谁有想法,我该怎么办呢?

2 个答案:

答案 0 :(得分:2)

您可以使用反射订阅多种类型:

// You need to change List<T> to List<Type>, and you need to only pass types here
public void subscribe(List<Type> listMessagesTypes)
{
    foreach(Type messageType in listMessagesTypes)
    {
        // find method "subscribe" on Messenger type
        MethodInfo method = typeof(Messenger).GetMethod("subscribe");

        // create a generic definition of method with specified type
        MethodInfo genericMethod = method.MakeGenericMethod(messageType);

        // invoke this generic method
        // the assumption is that your method signature is like this: doAction(IMessage message)
        genericMethod.Invoke(_messenger, new object[] { new Action<IMessage>(doAction)});
    }
}

该方法将被调用如下:

var listOfTypes = new List<Type>{ typeof(MessageA), typeof(MessageB)};
subscribe(listOfTypes);

答案 1 :(得分:-1)

除非在编译时知道其类型,否则不能使用通用订阅方法。 https://msdn.microsoft.com/en-us/library/f4a6ta2h.aspx

你可以尝试:

void subscribe(List<Type> listMessagesTypes, Action doAction)
{
   foreach (Type messageType in listMessagesTypes)         
     if (typeof(IMessage).IsAssignableFrom(messageType)
       _messenger.subscribe(messageType, doAction);
}

但是你仍然需要实现一个接受Type的订阅方法。