Как создать экземпляр универсального контейнера, такого как List <T>, где T указан в конфигурации в C # 4.0? - PullRequest
0 голосов
/ 16 ноября 2011

У меня есть приложение, в котором я хотел бы определить очереди сообщений в конфигурации. Поэтому я хотел бы указать в конфигурации некоторое количество типов сообщений, таких как «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"?

Кто-нибудь знает какой-либо другой способ создания группы MsgQueue из T, где T задается строкой во время выполнения?

Я использую C # 4.0, может ли мне помочь динамическое ключевое слово?

Спасибо!

Ответы [ 3 ]

1 голос
/ 16 ноября 2011

Вы можете использовать Type.GetType(string), а затем использовать его для создания экземпляра вашего универсального класса.

Например, это может создать список строк:

0 голосов
/ 16 ноября 2011

Это невозможно, потому что тип должен быть известен во время компиляции, а не во время выполнения.

Вы можете использовать рефлексию, но вы теряете строгую типизацию, и производительность падает (что может иметь или не иметь значения для вас)

Action<MsgBase> listener = GetListener(qType);
Type type = typeof(MsgQueue<>).MakeGenericType(Type.GetType("String"));
dynamic msgQueue = Activator.CreateInstance(type, listener);
//do whatever with msgQueue.
0 голосов
/ 16 ноября 2011

Я не думаю, что динамика здесь хороша.Вам нужно прибегнуть к старому доброму размышлению.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...