Передача типа, сгенерированного в RunTime (через TypeBuilder), в GenericClass - PullRequest
1 голос
/ 02 апреля 2011

Я хотел бы передать тип, сгенерированный во время выполнения (через TypeBuilder) в универсальный метод в универсальном классе. Я не могу передать его как объект, так как отражение используется для поиска различных свойств.

Как я понимаю, это невозможно сделать, так как генерики применяются во время компиляции, а не во время выполнения.

Я знаю, что могу изменить метод, например

public T Read()
{
     T data = new T()
     ...
     return data;
}

быть чем-то вроде

public object Read(Type newType)
{
     object data =  Activator.CreateInstance(newType);  
     ...
     return data;
}

но это, очевидно, теряет все преимущества обобщенных типов, когда тип известен, поэтому я, вероятно, закончу оба метода, что, к сожалению, означает также дублирование довольно многих других вспомогательных функций.

Есть ли лучший способ решить эту проблему?

Этот конкретный проект должен работать в рамках 3.5, но если это невозможно в 3.5, но под 4.0, я не возражаю, зная.

1 Ответ

4 голосов
/ 02 апреля 2011

Предполагая, что Read() является членом class Reader<T> where T : new(), вы можете вызвать универсальную версию следующим образом (возможно, используя другую перегрузку GetMethod(), если у вас более одного метода с именем Read для этого типа):

Type readerType = typeof(Reader<>).MakeGenericType(generatedType);
object result = readerType
                  .GetMethod("Read")
                  .Invoke(Activator.CreateInstance(readerType), new object[0]);

Таким образом, у вас есть преимущество дженериков внутри Read(), но не снаружи. В зависимости от того, что вы хотите сделать, может быть, было бы лучше использовать интерфейсы вместо универсальных. Ограничение new() можно эмулировать, генерируя тип фабрики для каждого сгенерированного типа, причем типы реализуют следующие (не сгенерированные) интерфейсы:

interface IWhatever { … }

interface IWhateverFactory
{
    IWhatever Create();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...