2012-01-23 19 views
11

Vì vậy, tôi có một lớp chung chung và nó có thể cần, bên trong một phương thức của nó, tự tạo ra một thể hiện của chính nó với một kiểu generic khác. . Điều này quan trọng bởi vì Repository này ánh xạ T tới một bảng cơ sở dữ liệu [đó là một ORMish tôi đang viết] và nếu lớp đại diện cho T có một bộ sưu tập biểu diễn bảng KHÁC tôi cần để có thể thể hiện và chuyển nó đến kho lưu trữ [ala Inception].
Tôi đang cung cấp phương pháp trong trường hợp nó giúp việc xem vấn đề trở nên dễ dàng hơn.C# Tạo một kiểu generic chưa biết ở thời gian chạy

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; 
      } 

Vì vậy, hãy cho GenericRepository và tôi muốn tạo một GenericRepository làm cách nào để thực hiện việc này? Dòng Tôi cần phải thay thế bằng một cái gì đó mà làm việc là

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

Làm thế nào là tài sản (một trong những loại 'Hệ thống .Collections.Generic') được khai báo trong mã C# của bạn? Đối số kiểu của nó là ' 'giống như đối số' GenericRepository 'sở hữu thuộc tính? – dasblinkenlight

+0

Không, về cơ bản nó chỉ là một bộ sưu tập chung của một lớp khác như là một tài sản trên một lớp. nghĩa là lớp Giáo viên có danh sách lớp học. Kho chứa lớp giáo viên và cũng phải xử lý lớp lớp, nhưng vì nó thực sự nhận được T nó phải tìm ra nó phải xử lý như thế nào bằng cách sử dụng sự phản chiếu – Jordan

+0

Vì vậy, thuộc tính trong lớp 'Teacher' được khai báo là' List Lớp học {/ * getter và/hoặc setter * /} '? Sẽ không 'Activator.CreateInstance (Property.GetType())' làm việc sau đó? – dasblinkenlight

Trả lời

28

Tôi nghĩ rằng bạn đang tìm kiếm MakeGenericType phương pháp:

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

Nếu có thể, tôi đang gặp phải 1 sự cố. Tôi không thể truy cập bất kỳ phương thức nào cho kho lưu trữ đã cho. Nếu tôi truy cập nó thông qua cửa sổ ngay lập tức, nơi nó thực hiện nói chung GenericRepository và tôi làm ? ((GenericRepository ) kho lưu trữ) .GetAll() Điều này hoạt động đúng cách, làm thế nào tôi có thể đúc nó đúng cách mã như vậy mà tôi không cần điều này? Rõ ràng tôi chỉ có thể làm điều đó trong cửa sổ ngay lập tức bởi vì tôi biết loại nó đại diện. – Jordan

+0

@Jordan, bạn có thể tạo một giao diện 'IRepository' không chung chung với phương thức' GetAll' trả về một mảng các đối tượng và thực hiện giao diện này một cách rõ ràng trong lớp 'GenericRepository '. Hoặc bạn có thể gọi phương thức động bằng cách sử dụng phản chiếu, nhưng nó chậm hơn ... –

+0

Ah ok. Ngoài ra tôi nhận ra nếu tôi tuyên bố nó là năng động thay vì var mà hoạt động – Jordan

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

Điều này sẽ tạo ra một thể hiện của 'GenericRepository ', kể từ 'tài sản .GetType() 'trả về' RuntimePropertyInfo' ... –

Các vấn đề liên quan