C#: IENUMERATOR 사용 명령문에서
-
06-09-2019 - |
문제
나는 어떻게 SingleOrFallback
방법이 구현되었습니다 Morelinq 그리고 내가 전에 보지 못한 것을 발견했습니다.
public static T SingleOrFallback<T>(this IEnumerable<T> source, Func<T> fallback)
{
source.ThrowIfNull("source");
fallback.ThrowIfNull("fallback");
using (IEnumerator<T> iterator = source.GetEnumerator())
{
if (!iterator.MoveNext())
{
return fallback();
}
T first = iterator.Current;
if (iterator.MoveNext())
{
throw new InvalidOperationException();
}
return first;
}
}
왜 IEnumerator<T>
안에 using
성명? 이것은 사용할 때 생각해야 할 것입니다. foreach
에 IEnumerable<T>
또한?
부수적 질문 : 이 방법은 정확히 무엇을합니까? 소스 시퀀스에 정확히 하나의 항목이 포함되지 않을 때마다 폴백 항목을 반환합니까?
해결책
IEnumerator<T>
확장 IDisposable
, 그래서 당신은 ~해야 한다 사용 설명서에 있습니다. foreach
자동으로이를 수행합니다. (비 게 니체 IEnumerator
그렇지 않습니다 연장하다 IDisposable
그러나 C# 컴파일러는 여전히 호출 할 코드를 생성합니다. Dispose
조건부. 이것은 C# 1.0과 1.2 사이의 (소수) 변경 중 하나였으며, 여기서 1.2는 어떤 이유로 .NET 1.1이있는 버전 배송입니다.)
여기 기사가 있습니다 반복자 블록의 맥락에서 이것이 중요한 이유를 설명합니다.
방법이 무엇을하는지 :
- 시퀀스가 비어 있으면 폴백 항목을 반환합니다.
- 시퀀스에 정확히 하나의 항목이 있으면 반환하십시오.
- 시퀀스에 하나 이상의 항목이 있으면 예외를 던지십시오.
추신 : Morelinq가 주목을 받고 있다는 것을 알게되어 반갑습니다 :)
다른 팁
일부 열거자는 처분되지 않으면 나쁘게 행동합니다. 이것은 일반적인 것과 마찬가지로 일반적인 것과 마찬가지로 사실입니다 (비 게 니체는 코드가 오리 유형을 처분하거나 idisposable에 캐스트 한 다음 idisposable.dispose를 호출해야합니다). ienumerator 객체가 폐기되도록하는 것은 습관의 문제로 좋습니다. 나는 알 수없는 유형의 ienumerable을 받아들이는 루틴의 정확성에 필요하다고 생각합니다.