2009-05-06 36 views
28

Tôi đang viết một ConfigurationElementCollection tùy chỉnh cho một ConfigurationHandler tùy chỉnh trong C# .NET 3.5 và tôi muốn hiển thị IEnumerator như một IEnumerator chung.Cách tốt nhất để chuyển đổi một IEnumerator thành một IEnumerator chung là gì?

Cách tốt nhất để đạt được điều này là gì?

Tôi hiện đang sử dụng mã:

 
public new IEnumerator<GenericObject> GetEnumerator() 
{ 
    var list = new List(); 
    var baseEnum = base.GetEnumerator(); 
    while(baseEnum.MoveNext()) 
    { 
    var obj = baseEnum.Current as GenericObject; 
    if (obj != null) 
     list.Add(obj); 
    } 
    return list.GetEnumerator(); 
} 

Cheers

Trả lời

45

Tôi không tin có bất cứ điều gì trong khuôn khổ, nhưng bạn có thể dễ dàng viết một:

IEnumerator<T> Cast<T>(IEnumerator iterator) 
{ 
    while (iterator.MoveNext()) 
    { 
     yield return (T) iterator.Current; 
    } 
} 

Thật hấp dẫn khi chỉ gọi Enumerable.Cast<T> từ LINQ và sau đó gọi GetEnumerator() về kết quả - nhưng nếu lớp học của bạn đã triển khai IEnumerable<T>T là một kiểu giá trị, hoạt động như một no-op, do đó cuộc gọi GetEnumerator() đệ quy và ném một số StackOverflowException. An toàn để sử dụng return foo.Cast<T>.GetEnumerator(); khi foo chắc chắn là một đối tượng khác nhau (không ủy quyền lại đối tượng này) nhưng nếu không, có lẽ bạn nên sử dụng mã ở trên.

+7

Bạn không thể chỉ trả lại Điều tra viên từ diễn viên? trả lại this.Cast () .GetEnumerator(); – flq

+0

Frank: Bạn hoàn toàn đúng :) –

+0

Thats nó cảm ơn. Cảm ơn tất cả các hồi đáp của bạn. – zonkflut

3

IEnumerable<T> đã xuất phát từ IEnumerable nên không cần phải làm bất kỳ chuyển đổi. Bạn có thể chỉ đơn giản là đúc nó ... cũng thực sự nó ngầm không có diễn viên cần thiết.

IEnumerable<T> enumerable = GetGenericFromSomewhere(); 
IEnumerable sadOldEnumerable = enumerable; 
return sadOldEnumerable.GetEnumerator(); 

Đi vòng cách nào khác không phải là nhiều khó khăn hơn với LINQ:

var fancyEnumerable = list.OfType<GenericObject>(); 
return fancyEnumerable.GetEnumerator(); 
+0

Lỗi xấu của tôi bỏ phần chung với định nghĩa phương thức của tôi – zonkflut

+2

Bạn đang nhầm lẫn IEnumerable và IEnumerator. IEnumerable có nguồn gốc từ IEnumerable và IEnumerator có nguồn gốc từ IEnumerator.Nó không có ý nghĩa nhiều khi nói "IEnumerable theEnumerator" bởi vì một đếm được không phải là một điều tra viên. –

+0

truyền không hoạt động như trong đối tượng cha mẹ bộ sưu tập được lưu trữ trong một ArrayList. – zonkflut

0

Bạn có thể sử dụng OfType<T>Cast<T>.

public static IEnumerable Digits() 
{ 
    return new[]{1, 15, 68, 1235, 12390, 1239}; 
} 

var enumerable = Digits().OfType<int>(); 
foreach (var item in enumerable) 
    // var is here an int. Without the OfType<int(), it would be an object 
    Console.WriteLine(i); 

Để có được một IEnumerator<T> thay vì một IEnumerable<T> bạn chỉ có thể thực hiện cuộc gọi đến GetEnumerator()

var enumerator = Digits().OfType<int>().GetEnumerator(); 
0

này làm việc cho tôi.

IEnumerator<DataColumn> columnEnumerator = dt.Columns.Cast<DataColumn>().GetEnumerator(); 
0

Tôi đã chạy vào cùng một vấn đề về Stack Overflow được đề cập là một số nhận xét. Trong trường hợp của tôi đó là do thực tế là các cuộc gọi GetEnumerator cần thiết để được các cơ sở.GetEnumerator nếu không bạn lặp trong định nghĩa lại GetEnumerator của riêng bạn.

Đây là mã đã ném tràn ngăn xếp. Việc sử dụng các báo cáo kết quả foreach gọi hàm GetEnumerator cùng tôi đang cố gắng để tình trạng quá tải:

public new IEnumerator<T> GetEnumerator() 
{ 
    foreach (T type in this) 
    { 
     yield return type; 
    } 
} 

Tôi đã kết thúc với một phiên bản đơn giản của các bài bản gốc là bạn không cần phải sử dụng một người giữ danh sách.

public class ElementCollection<T> : ConfigurationElementCollection, IList<T> 
    ... 
    public new IEnumerator<T> GetEnumerator() 
    { 
     var baseEnum = base.GetEnumerator(); 
     while (baseEnum.MoveNext()) 
     { 
      yield return baseEnum.Current as T; 
     } 
    } 
    ... 
} 
Các vấn đề liên quan