2009-12-14 27 views
7

Trong một số phần của mã của tôi, tôi đã vượt qua một tập hợp các đối tượng thuộc loại T. Tôi không biết sự va chạm cụ thể nào mà tôi sẽ được thông qua, khác với sự va chạm của nó IEnumerable.Cách lấy loại có trong bộ sưu tập thông qua sự phản chiếu

Khi chạy, tôi cần tìm ra loại T nào (ví dụ: System.Double, System.String, v.v ...).

Có cách nào để tìm ra không?

CẬP NHẬT: Tôi có thể làm rõ thêm một chút ngữ cảnh mà tôi đang làm việc (nhà cung cấp LINQ).

chức năng của tôi có một chữ ký như sau, nơi tôi nhận được các loại của bộ sưu tập như một tham số:

string GetSymbolForType(Type collectionType) 
{ 

} 

Có cách nào từ collectionType để có được các đối tượng chứa gõ?

+1

từ loại bộ sưu tập, bạn chỉ có thể nhận loại đối tượng chứa trong bộ sưu tập chung. Nếu bạn làm việc với các bộ sưu tập cổ điển, bạn sẽ không có cơ hội tốt ở đây ngoài việc lặp lại các đối tượng và yêu cầu cụ thể cho các loại của chúng. –

Trả lời

14

Từ Matt Warren's Blog:

internal static class TypeSystem { 
    internal static Type GetElementType(Type seqType) { 
     Type ienum = FindIEnumerable(seqType); 
     if (ienum == null) return seqType; 
     return ienum.GetGenericArguments()[0]; 
    } 
    private static Type FindIEnumerable(Type seqType) { 
     if (seqType == null || seqType == typeof(string)) 
      return null; 
     if (seqType.IsArray) 
      return typeof(IEnumerable<>).MakeGenericType(seqType.GetElementType()); 
     if (seqType.IsGenericType) { 
      foreach (Type arg in seqType.GetGenericArguments()) { 
       Type ienum = typeof(IEnumerable<>).MakeGenericType(arg); 
       if (ienum.IsAssignableFrom(seqType)) { 
        return ienum; 
       } 
      } 
     } 
     Type[] ifaces = seqType.GetInterfaces(); 
     if (ifaces != null && ifaces.Length > 0) { 
      foreach (Type iface in ifaces) { 
       Type ienum = FindIEnumerable(iface); 
       if (ienum != null) return ienum; 
      } 
     } 
     if (seqType.BaseType != null && seqType.BaseType != typeof(object)) { 
      return FindIEnumerable(seqType.BaseType); 
     } 
     return null; 
    } 
} 
+1

Điều này đã làm các trick. Cảm ơn bạn. –

0
Type t = null 
foreach(object o in list) 
{ 
o.GetType(); 
} 

sẽ cho bạn loại đối tượng.

Sau đó, có lẽ bạn nên thử nghiệm với nhiều loại mong muốn của bạn:

if(t == typeof(myClass)) 
{ 
dosomething(); 
} 
else if (t == typeof(myOtherClass)) 
{ 
dosomethingelse(); 
} 
0

Cant bạn chỉ cần sử dụng t.GetType() để thực hiện điều này.

0

Tại sao không chỉ triển khai IEnumerable<T> thay thế? EG:

public void MyFunc<T>(IEnumerable<T> objects)

Khác hơn thế, bạn muốn được tốt hơn kiểm tra kiểu của từng đối tượng cá nhân sử dụng is hoặc .GetType hơn là cố gắng làm việc nó ra từ container riêng của mình.

Nếu đó không phải là một lựa chọn mặc dù và bạn thực sự cần phải biết loại container căn cứ bạn muốn về cơ bản phải kiểm tra sử dụng is để xem những gì giao diện nó thực hiện (EG: IList<int> vv). Tỷ lệ cược là loại mảng của bạn sẽ là một chung chung có nghĩa là cố gắng để làm việc trở lại từ tên của nó xuống đến loại dữ liệu của nó sẽ được khá lộn xộn.

8
myCollection.GetType().GetGenericArguments() 

sẽ trả về một mảng của loại args.

+4

chỉ hoạt động trên các loại chung. –

0

Vâng tôi cách cách cuối ở đây nhưng không nên làm việc này:

public static bool ThatCollectionIsOfType<T>(IEnumerable<T> collection, Type got) 
    { 
     if (**typeof(T)** == got) //this line should be good to go... 
     { 
      return true; 
     } 

    } 
0

tôi sử dụng rất nhiều năng động và đây là một vấn đề trong từng thời kỳ.

Matt Davis đóng đinh nó nhưng bạn cần chỉ số :)

public static void PopulateChildCollection<T>(T currentObject, string singlePropertyName) 
{ 
    dynamic currentObjectCollection = ReflectionTools.GetPropertyValue(currentObject, singlePropertyName); 
    Type collectionType = currentObjectCollection.GetType().GetGenericArguments()[0]; 

Các loại sẽ là những gì bạn mong đợi, nó là loại của đối tượng chứa trong bộ sưu tập và không phải bất kỳ loại generic xung quanh nó.

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