Ienumerator를 일반 iEenumerator로 변환하는 가장 좋은 방법은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/828342

  •  06-07-2019
  •  | 
  •  

문제

C#.NET 3.5에서 사용자 정의 구성 핸들러에 대한 사용자 정의 구성에 대한 COLLECTION을 작성하고 있으며 IENUMERATOR를 일반적인 iEenumerator로 노출 시키려고합니다.

이것을 달성하는 가장 좋은 방법은 무엇입니까?

현재 코드를 사용하고 있습니다.

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

건배

도움이 되었습니까?

해결책

나는 프레임 워크에 아무것도 없다고 생각하지 않지만 쉽게 쓸 수 있습니다.

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

그냥 전화하려는 유혹입니다 Enumerable.Cast<T> LINQ에서 전화하십시오 GetEnumerator() 결과적으로 - 그러나 수업이 이미 구현되는 경우 IEnumerable<T> 그리고 T No-OP 역할을하는 값 유형이므로 GetEnumerator() 호출은 되풀이되고 던졌습니다 StackOverflowException. 사용하기에 안전합니다 return foo.Cast<T>.GetEnumerator(); 언제 foo 확실히 a 다른 객체 (이것으로 다시 위임하지 않음) 그러나 그렇지 않으면 위의 코드를 사용하는 것이 가장 좋습니다.

다른 팁

IEnumerable<T> 이미 파생됩니다 IEnumerable 따라서 전환 할 필요가 없습니다. 당신은 단순히 캐스트 할 수 있습니다 ... 실제로는 캐스트가 필요하지 않습니다.

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

다른 방법으로가는 것은 LINQ에서는 그리 어렵지 않습니다.

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

언급 된 동일한 스택 오버플로 문제가 언급 된 일부 의견입니다. 제 경우에는 GetEnumerator 호출이 Base에 있어야한다는 사실 때문이었습니다. GetEnumerator는 자신의 GetEnumerator 재정의 내에서 루프입니다.

이것은 스택 오버플로를 던지는 코드입니다. foreach 문을 사용하면 과부하하려는 동일한 getEnumerator 기능을 호출합니다.

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

목록 홀더를 사용할 필요가 없으므로 원래 게시물의 단순화 된 버전으로 끝났습니다.

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

당신이 사용할 수있는 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);

얻기 위해 IEnumerator<T> 대신 IEnumerable<T> 당신은 그냥 전화를 할 수 있습니다 GetEnumerator()

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

이것은 나를 위해 작동합니다.

IEnumerator<DataColumn> columnEnumerator = dt.Columns.Cast<DataColumn>().GetEnumerator();
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top