2009-10-03 3 views
2

IEnumerable<T>을 구현하는 클래스가 있다고 가정 해 보겠습니다. 현재 GetEnumerator() 메서드에서 yield 키워드를 사용합니다. 하지만 지금은 조금 더 할 필요가 있습니다. 예를 들어, 나 혼자서 정리하고 싶습니다. 이를 간과하기 전에는 IEnumerator<T> 인터페이스를 구현해야합니다. 하지만 내가 어디에서해야한다고 했니?C# : 사용자 지정 IEnumerator를 구현할 위치 <T>

클래스 자체에서 구현해야하며 GetEnumerator()this을 반환해야합니까? 아니면 개인 수업에서 그것을 숨기는 것이 더 좋을까요? 아니면 완전히 다른 클래스일까요? 이것에 대한 몇 가지 일반적인 관행은 무엇입니까?

답변

6

foreach 루프의 끝과 같이 열거자를 삭제할 때 일부 리소스를 정리해야하는 경우 보유하고있는 리소스를 사용하여 수행 할 수 있습니다. try/finally 블록을 반복자 메소드. 이처럼

:

모든 작업이 완료
public IEnumerator<T> GetEnumerator() 
{ 
    try 
    { 
     // your iterator code here 
    } 
    finally 
    { 
     // cleanup code here 
    } 
} 

.

+0

try 블록 안에 양보 할 수 없다고 생각 했습니까? –

+0

@ csharptest.net - 그 후에 finally 블록 만 있으면 가능합니다. 그것은 허용되지 않는 잡기입니다. –

+0

Brilliant. 이것이 가능했다는 것을 전혀 몰랐습니다. 테스트 한 결과, 'yield returns'는 try 블록에 존재할 수 있습니다. * 그러나 * finally 블록에는 존재할 수 없습니다. @Earwicker가 말했듯이,'catch' 블록을 가진'try' 블록에는 존재할 수 없습니다. – Svish

2

나는 IEnumerator 클래스 < T>에 대해 갈 것입니다. 이것은 컬렉션의 일부가 아닌 상태 (현재 위치)를 저장할 필요가 있지만 열거 프로세스의 일부입니다.

+0

'yield returns'에 대해 읽어 볼 수 있습니다. 메소드를 작성하는 것처럼 보이지만 사실 상태가있는 클래스를 생성하고있는 것입니다. –

+0

@ Earwicker, 네, 알고 있습니다. 그래서 개인 수업 제안의 이유가되었습니다. 내가 비슷한 결과를 낳을 것이라고 생각하기 때문에. 비록 내가 단서를 가지고 있지는 않지만 : – Svish

0

이 클래스를 작성하지 않아도됩니다. 반복자 메서드는 IEnumerable<T>을 반환 할 수 있으므로 클래스가 IEnumerable<T> 만 구현하면되고 그 밖의 것은 필요하지 않으면 전체적인 반복기 메서드를 작성하면됩니다.

그렇지 않은 경우 GetEnumerator을 수행하는 반복기 메소드를 사용하여 IEnumerable<T>을 구현하는 외부 클래스를 고수해야하므로 반복 후에 정리하기가 어렵지 않습니다.

IEnumerator<T>IDisposable에서 파생됩니다. 반복기 메서드는 finally 블록 또는 마지막 코드 yield return 다음의 코드를 실행하여 Dispose을 구현합니다.

+0

코드? 그게 어떻게 효과가 있니? 특히 '수익률 반환'이 무한 루프에 있었던 경우 ... – Svish

+0

나는 정말 나쁜 말을했습니다! 마지막'yield return '이후의 코드는 도달 할 수 있으면 실행되지만'Dispose'가 아닌'IEnumerator.MoveNext'를 마지막으로 호출 할 때 실행됩니다. 수익률 반환 값이 무한 루프이면 해당 루프 뒤의 코드에 도달 할 수 없으며 컴파일러에서 알려줍니다. 그렇지 않은 경우 호출자가 콜렉션의 모든 항목을 열거 한 후에 해당 코드가 실행됩니다.따라서 finally 블록을 사용하여 열거 형을 완료했는지 또는 중단했는지에 관계없이 실행하고 열거 형을 취소하지 않은 경우에만 실행하려면 코드를 메서드 끝에 넣습니다. –

관련 문제