如何实例化一个通用容器,例如List <t>,其中在C#4.0的config中指定了T?</t>

时间:2011-11-16 18:01:43

标签: .net c#-4.0

我有一个应用程序,我想在config中定义消息队列。所以我想在config中指定一些消息类型,例如“app.msg.UpdateMsg”或“app.msg.SnapshotMsg”,以便为其创建队列。

假设我的消息队列类看起来像这样:

public class MsgQueue<T> : where T: MsgBase, new()
{
    private readonly Action<T> _queueListener;

    public MsgQueue(Action<T> queueListener)
    {
        _queueListener = queueListener;
    }
    ...
}

现在假设我有另一个想要从配置中读取其中列出的队列类型的类,并将它们放入容器中。像这样:

public class QueueManager
{
    // We know T is a MsgBase, but not much else :(
    private List<MsgQueue<MsgBase>> _msgQueues = new List<MsgQueue<MsgBase>>();

    public QueueManager()
    {
        List<string> configuredQueueTypes = GetQueueTypesFromConfig();

        PopulateMsgQueues(configuredQueueTypes);
    }

    private void PopulateMsgQueues(List<string> qTypes)
    {
        foreach (string qType in qTypes)
        {
            Action<MsgBase> listener = GetListener(qType);

            // What goes here? How do I create a MsgQueue<qType>?
        }
    }
    ...
}

如果可能,我该如何定义PopulateMsgQueues()?

如果我可以在配置中指定“app.MsgQueue of app.msg.UpdateMsg”这样的话,是否可能(并且会有所帮助)?

有没有人知道任何其他方法来实例化一堆T的MsgQueue,其中T在运行时由字符串指定?

我正在使用C#4.0,动态关键字可以帮助我吗?

谢谢!

3 个答案:

答案 0 :(得分:1)

您可以使用Type.GetType(string)然后使用它来实例化您的泛型类。

例如,这将实例化一个字符串列表:

Type type = typeof(List<>).MakeGenericType(Type.GetType("String"));
Activator.CreateInstance(type);

答案 1 :(得分:0)

我不认为动态在这里很好。你需要诉诸旧的反思。

答案 2 :(得分:0)

这是不可能的,因为类型需要在编译时知道,而不是运行时。

你可以使用反射,但是你失去了强类型并且有一个性能损失(对你来说可能或不重要)

Action<MsgBase> listener = GetListener(qType);
Type type = typeof(MsgQueue<>).MakeGenericType(Type.GetType("String"));
dynamic msgQueue = Activator.CreateInstance(type, listener);
//do whatever with msgQueue.