2012-01-23 2 views
11

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

Это важно, потому что этот репозиторий сопоставляет T с таблицей базы данных [это ORMish, которую я пишу], и если класс, представляющий T, имеет коллекцию, представляющую таблицу ANOTHER, мне нужно иметь возможность указать ее и передать ее репозиторий [ala Inception].
Я предоставляю метод на случай, если вам будет легче увидеть проблему.

private PropertiesAttributesAndRelatedClasses GetPropertyAndAttributesCollection() 
     { 
    // Returns a List of PropertyAndAttributes 
    var type = typeof(T); 
//For type T return an array of PropertyInfo 

    PropertiesAttributesAndRelatedClasses PAA = new PropertiesAttributesAndRelatedClasses(); 
//Get our container ready 

     PropertyAndAttributes _paa; 
     foreach (PropertyInfo Property in type.GetProperties()) 
//Let's loop through all the properties. 

      {      
     _paa = new PropertyAndAttributes(); 
//Create a new instance each time. 

     _paa.AddProperty(Property); 
//Adds the property and generates an internal collection of attributes for it too 

     bool MapPropertyAndAttribute = true; 
     if (Property.PropertyType.Namespace == "System.Collections.Generic") 
    //This is a class we need to map to another table 
       { 
        PAA.AddRelatedClass(Property); 
       //var x = Activator.CreateInstance("GenericRepository", Property.GetType().ToString()); 
        } 
        else 
        { 
         foreach (var attr in _paa.Attrs) 
         { 
          if (attr is IgnoreProperty) 
//If we find this attribute it is an override and we ignore this property. 
          { 
           MapPropertyAndAttribute = false; 
           break; 
          } 
         } 
        } 
        if (MapPropertyAndAttribute) 
         PAA.AddPaa(_paa); 
      //Add this to the list. 
       } 
       return PAA; 
      } 

Так дали GenericRepository, и я хочу сделать GenericRepository как бы я это сделать? линия мне нужно заменить чем-то, что работает,

//     var x = Activator.CreateInstance("GenericRepository", Property.GetType().ToString()); 
+0

Как это свойство (один из типов 'System .Collections.Generic'), объявленный в коде C#? Является ли его аргумент типа «» тем же, что и у «GenericRepository », который владеет свойством? – dasblinkenlight

+0

Нет, в основном это всего лишь общая коллекция другого класса как свойство класса. Т.е. класс Учителя имеет список классов классов. Репозиторий получает класс преподавателя и должен также обрабатывать класс классов, но поскольку он действительно получает T, он должен выяснить, что он должен обрабатывать, используя отражение. – Jordan

+0

Итак, это свойство в классе 'Учитель', объявленном как« Список Классы {/ * геттер и/или сеттер * /} '? Не будет ли 'Activator.CreateInstance (Property.GetType()) работать? – dasblinkenlight

ответ

28

Я думаю, что вы ищете MakeGenericType метод:

// Assuming that Property.PropertyType is something like List<T> 
Type elementType = Property.PropertyType.GetGenericArguments()[0]; 
Type repositoryType = typeof(GenericRepository<>).MakeGenericType(elementType); 
var repository = Activator.CreateInstance(repositoryType); 
+0

Если возможно, я столкнулся с одной проблемой. Я не могу получить доступ к каким-либо методам для данного репозитория. Если я обращаюсь к нему через непосредственное окно, где он сделал, скажите GenericRepository и я делаю ? (Репозиторий GenericRepository )) .GetAll() Это правильно работает, как я могу его правильно направить в код такой, что мне это не нужно? Очевидно, я могу сделать это только в непосредственном окне, потому что знаю тип, который он представляет. – Jordan

+0

@Jordan, вы могли бы создать не общий интерфейс IREPOSTIT с помощью метода GetAll, который возвращает массив объектов и явно реализует этот интерфейс в классе «GenericRepository ». Или вы можете вызвать метод динамически с помощью отражения, но он медленнее ... –

+0

А, ок. Также я понял, объявляю ли я его динамическим, а не var, который работает – Jordan

4
Activator.CreateInstance(typeof(GenericRepository<>).MakeGenericType(new Type[] { Property.GetTYpe() })) 
+1

Это создаст экземпляр 'GenericRepository ', поскольку 'Property .GetType() 'возвращает' RuntimePropertyInfo' ... –

Смежные вопросы