2012-01-23 3 views
11

그래서 나는 클래스를 가지고 있으며, 그 클래스의 메서드 내에서 자체가 다른 종류의 generic을 가진 자체의 인스턴스를 만들 필요가 있습니다. 형식은 relfection을 통해 얻어집니다. .C# 런타임시 알 수없는 제네릭 형식 만들기

이 리포지토리가 T를 데이터베이스 테이블에 매핑하기 때문에 중요합니다. [쓰는 중 ORMish입니다.] T를 나타내는 클래스가 다른 테이블을 나타내는 컬렉션을 가지고 있으면이를 인스턴스화하여 저장소 [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을 만들고 싶어? I 작동 뭔가 교체해야하는 줄은 난 당신이 MakeGenericType 방법을 찾고 있다고 생각

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

어떻게 재산 (유형 중 하나 인'시스템 .Collections.Generic') 귀하의 C# 코드에서 선언? 타입 인자''이 그 속성을 소유하고있는'GenericRepository '과 같은가? – dasblinkenlight

+0

아니요, 기본적으로 클래스의 속성으로 다른 클래스의 일반적인 컬렉션입니다. 즉 교사 클래스에는 클래스 클래스 목록이 있습니다. 저장소는 교사 클래스를 가져오고 클래스 클래스도 처리해야하지만 실제로는 T를 얻으므로 반향을 사용하여 처리해야하는 것이 무엇인지 파악해야합니다. – Jordan

+0

Teacher 클래스의 속성이'List {/ * getter 및/또는 setter * /}'? 'Activator.CreateInstance (Property.GetType())'이 작동하지 않겠습니까? – dasblinkenlight

답변

28

입니다 :

// 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

내가 할 수있는 한, 나는 1 문제로 달리고있다. 주어진 저장소에 대한 메소드에 액세스 할 수 없습니다. GenericRepository 을 직접 작성한 창을 통해 액세스 할 경우 ? ((GenericRepository ) repository) .GetAll() 올바르게 작동합니다. 어떻게 올바르게 캐스팅 할 수 있습니까? 내가 필요로하지 않는 코드? 분명히 유형을 알고 있기 때문에 직접적인 창에서만 그것을 할 수 있습니다. – Jordan

+0

@Jordan, 객체 배열을 반환하는'GetAll' 메쏘드로 비 제네릭 IRepository 인터페이스를 생성하고이 인터페이스를'GenericRepository '클래스에 명시 적으로 구현할 수 있습니다. 또는 리플렉션을 사용하여 동적으로 메서드를 호출 할 수 있지만 속도가 느립니다. –

+0

아 좋아요. 또한 작동하는 var 대신 동적으로 선언하면 실현됩니다 – Jordan

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

그러면 'Property .GetType()'은'RuntimePropertyInfo'를 반환합니다 ... –

관련 문제