2009-03-10 35 views
42

Tôi đang cố gắng để thực hiện các diễn viên sauCast nhận đối tượng vào một danh sách <object> hay IEnumerable <object>

private void MyMethod(object myObject) 
{ 
    if(myObject is IEnumerable) 
    { 
     List<object> collection = (List<object>)myObject; 
     ... do something 
    } 
    else 
    { 
     ... do something 
    } 
} 

Nhưng tôi luôn luôn kết thúc với excepction sau:

Không thể cast đối tượng của loại ' System.Collections.Generic.List 1[MySpecificType]' to type 'System.Collections.Generic.List 1 [System.Object] '

Tôi thực sự cần điều này để làm việc vì phương pháp này cần phải rất chung chung để nhận các đối tượng đơn lẻ và bộ sưu tập cả hai loại không xác định.

Điều này có thể thực hiện được không, hoặc có cách nào khác để hoàn thành điều này không.

Cảm ơn bạn.

Trả lời

50

C# 4 sẽ có hiệp biến và contravariant thông số mẫu, nhưng cho đến khi đó bạn phải làm một cái gì đó nongeneric như

IList collection = (IList)myObject; 
+0

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

+1

@Sergio, Bạn nên kiểm tra xem myObject có triển khai thực hiện IList thay vì IEnumerable trước khi truyền nếu bạn muốn tránh nguy cơ lỗi thời gian chạy. Nhiều bộ sưu tập dựng sẵn thực hiện IEnumerable nhưng không phải là IList (ví dụ, Dictionary <>, HashSet <>, Hashtable, Queue, Stack etc). – LukeH

+0

@Luke: Nếu nó là một Danh sách (được ngụ ý bởi câu hỏi), nó sẽ thực hiện IList. – erikkallen

2

Làm thế nào về

List<object> collection = new List<object>((IEnumerable)myObject); 
46

Bạn không thể cast một IEnumerable <T> vào một danh sách <T>.

Nhưng bạn có thể thực hiện điều này bằng cách dùng LINQ:

var result = ((IEnumerable)myObject).Cast<object>().ToList(); 
+0

Cái này cũng hoạt động. Cảm ơn bạn. –

+2

Thao tác này cũng tạo danh sách mới thay vì truyền danh sách gốc. –

6

Bạn có thực sự cần nhiều thông tin hơn đồng bằng IEnumerable cung cấp cho bạn? Chỉ cần đúc nó và sử dụng foreach với nó. Tôi phải đối mặt chính xác tình hình tương tự trong một số bit của Protocol Buffers, và tôi đã tìm thấy rằng đúc để IEnumerable (hoặc IList để truy cập nó như một danh sách) hoạt động rất tốt.

9

Vấn đề là, bạn đang cố gắng để upcast đến một đối tượng phong phú hơn. Bạn chỉ cần thêm các mục vào một danh sách mới:

if (myObject is IEnumerable) 
{ 
    List<object> list = new List<object>(); 
    var enumerator = ((IEnumerable) myObject).GetEnumerator(); 
    while (enumerator.MoveNext()) 
    { 
     list.Add(enumerator.Current); 
    } 
} 
+0

là công trình này ?? –

0

Mã này đã làm việc cho tôi

List<Object> collection = new List<Object>((IEnumerable<Object>)myObject); 
1

Phải tham gia vui chơi ...

private void TestBench() 
    { 
     // An object to test 
     string[] stringEnumerable = new string[] { "Easy", "as", "Pi" }; 

     ObjectListFromUnknown(stringEnumerable); 
    } 

    private void ObjectListFromUnknown(object o) 
    { 
     if (typeof(IEnumerable<object>).IsAssignableFrom(o.GetType())) 
     { 
      List<object> listO = ((IEnumerable<object>)o).ToList(); 
      // Test it 
      foreach (var v in listO) 
      { 
       Console.WriteLine(v); 
      } 
     } 
    } 
0

Bạn cần phải gõ sử dụng làm nhà điều hành như thế này.

private void MyMethod(object myObject) 
{ 
if(myObject is IEnumerable) 
{ 
    List<object> collection = myObject as(List<object>); 
    ... do something 
} 
else 
{ 
    ... do something 
} 
}  
Các vấn đề liên quan