2009-12-04 21 views
48

Cách xác định xem đối tượng có thuộc loại IEnumerable <T> không?Xác định xem bộ sưu tập có thuộc loại IEnumerable <T>

Code:

namespace NS { 
    class Program { 
     static IEnumerable<int> GetInts() { 
      yield return 1; 
     } 
     static void Main() { 
      var i = GetInts(); 
      var type = i.GetType(); 
      Console.WriteLine(type.ToString()); 
     } 
    } 
} 

Output:

NS.1.Program+<GetInts>d__0 

Nếu tôi thay đổi GetInts trở IList, mọi thứ đều OK đầu ra là:

System.Collections.Generic.List`1[System.Int32] 

Và đây trả về false:

namespace NS { 
    class Program { 
     static IEnumerable<int> GetInts() { 
      yield return 1; 
     } 
     static void Main() { 
      var i = GetInts(); 
      var type = i.GetType(); 
      Console.WriteLine(type.Equals(typeof(IEnumerable<int>))); 
     } 
    } 
} 

Trả lời

98

Nếu bạn có nghĩa là các bộ sưu tập , sau đó chỉ cần as:

var asEnumerable = i as IEnumerable<int>; 
if(asEnumerable != null) { ... } 

Tuy nhiên, tôi giả sử (từ ví dụ) mà bạn có một Type:

Đối tượng sẽ không bao giờ là "của" loại IEnumerable<int> - nhưng nó có thể triển khai nó; Tôi hy vọng rằng:

if(typeof(IEnumerable<int>).IsAssignableFrom(type)) {...} 

sẽ làm. Nếu bạn không biết T (int ở trên), sau đó rà soát tất cả các giao diện thực hiện:

static Type GetEnumerableType(Type type) { 
    foreach (Type intType in type.GetInterfaces()) { 
     if (intType.IsGenericType 
      && intType.GetGenericTypeDefinition() == typeof(IEnumerable<>)) { 
      return intType.GetGenericArguments()[0]; 
     } 
    } 
    return null; 
} 

và gọi:

Type t = GetEnumerableType(type); 

nếu điều này là vô giá trị, nó không phải là IEnumerable<T> cho bất kỳ T - nếu không hãy kiểm tra t.

+17

Chỉ cần nhớ rằng 'System.String' thực hiện' IEnumerable '. – mayu

+1

@Tymek thực sự - Tôi làm khá nhiều công việc thư viện xử lý các kiểu nguyên thủy và sẵn có, và hầu như luôn luôn cần thiết để rút ra các kịch bản như 'string' * trước khi áp dụng các khái quát hóa, vì những lý do đó. –

+4

nếu loại là ICollection , mà thực hiện IEnumerable , nếu tuyên bố không đánh giá đúng. Có cách nào để nói rằng nó là IEnumerable hoặc bất kỳ lớp con của nó? –

3

i thuộc loại NS.1.Program+<GetInts>d__0, là loại phụ của IEnumerable<int>. Do đó, bạn có thể sử dụng hoặc

if (i is IEnumerable<int>) { ... } 

hoặc IsAssignableFrom (như trong câu trả lời của Marc).

1

Bạn có thể sử dụng từ khóa is.

[TestFixture] 
class Program 
{ 
    static IEnumerable<int> GetInts() 
    { 
     yield return 1; 
    } 

    [Test] 
    static void Maasd() 
    { 
     var i = GetInts(); 
     Assert.IsTrue(i is IEnumerable<int>); 
    } 
} 
13

Cùng kỹ thuật như câu trả lời của Marc, nhưng Linqier:

namespace NS 
{ 
    class Program 
    { 
     static IEnumerable<int> GetInts() 
     { 
      yield return 1; 
     } 

     static void Main() 
     { 
      var i = GetInts(); 
      var type = i.GetType(); 
      var isEnumerableOfT = type.GetInterfaces() 
       .Any(ti => ti.IsGenericType 
        && ti.GetGenericTypeDefinition() == typeof(IEnumerable<>)); 
      Console.WriteLine(isEnumerableOfT); 
     } 
    } 
} 
7

Làm thế nào để xác định xem đối tượng là loại IEnumerable <T>?

Vui lòng sử dụng phương pháp mở rộng tốt, cực nhỏ này để xác định xem có đối tượng nào triển khai giao diện IEnumerable hay không. Nó mở rộng loại đối tượng đối tượng, vì vậy bạn có thể thực thi nó bằng bất kỳ cá thể nào của bất kỳ đối tượng nào bạn đang sử dụng.

public static class CollectionTestClass 
{ 
    public static Boolean IsEnumerable<T>(this Object testedObject) 
    { 
     return (testedObject is IEnumerable<T>); 
    } 
} 
13

Kể từ IEnumerable <T> kế thừa IEnumerable (không chung chung) và nếu bạn không cần phải biết khi nào một loại chỉ là IEnumerable và không IEnumerable <T> sau đó bạn có thể sử dụng:

if (typeof(IEnumerable).IsAssignableFrom(srcType)) 
Các vấn đề liên quan