2011-08-30 2 views
20

이미 question on SO about "possible multiple enumerations"이 있지만이 질문은보다 구체적입니다. "IsNullOrEmpty"검사에서도 "IEnumerable의 여러 열거 가능"경고를 표시합니다.

입력으로서 IEnumerable<string> 소요의 각 요소에 대하여 소정의 방법을 실행하기 방법 고려 사항 : 상기 코드의

public static bool SomeMethod(IEnumerable<string> enumerable) 
{ 
    if (enumerable.IsNullOrEmpty()) 
    { 
     // throw exception. 
    } 
    else 
    { 
     return (enumerable.All(SomeBooleanMethod)); 
    } 
} 

IsNullOrEmpty

실행 단지 확장 방법
return (!ReferenceEquals(enumerable, null) || enumerable.Any()); 

문제는 ReSharper가 "가능한 여러 개의 IEnumerable 열거 형"에 대해 경고한다는 것입니다. 실제로 이것이 실제로 문제가 될 수 있는지 여부는 알 수 없습니다.

경고의 의미를 이해하지만 무효 또는 비어 있음을 확인하고 예외를 던질 필요가 있다면이 상황에서 실제로 무엇을 할 수 있습니까?

+0

빈 시퀀스가 ​​전달 된 경우 왜이 메소드를 throw 하시겠습니까? "이 (빈) 시퀀스의 모든 구성원에게 무언가를하십시오"라는 의미는 완벽하게 분명합니다. 또한'== null'이 아닌'ReferenceEquals()'를 사용하는 특별한 이유가 있습니까? – AakashM

+0

실제로 이것은 아닙니다. 그러나 이제 이것이 생성자라고 상상해보십시오. 빈 시퀀스에서 객체를 만들 수없는 경우 exceptio를 던지지 않아야합니까? – User

+1

물론, 당신이 할 수있는 일이 정말로 없다면; 그러나 일반적으로 * 빈 시퀀스는 비어 있지 않은 시퀀스처럼 잘 처리되어야한다고 말합니다. 'List <>'는 빈 시퀀스로부터 구성하는 것이 매우 행복합니다. 당연히 나는 일반화에서만 말하고있다. 당신은 당신의 상황에 대한 상세한 내용을 알고 있습니다. – AakashM

답변

30

이는 IEnumerable을 두 번 이상 반복적으로 수행한다는 것을 의미합니다. 먼저 Any() (적어도 반복을 초기화하여 열거 형 요소를 반환해야하는지 확인해야 함)으로 두 번째로 All (처음부터 반복됩니다).

ReSharper가 경고하는 이유는 열거 형을 열거하면 부작용이 생길 수 있으며 실수로 두 번 반복하면 부작용이 두 번 발생할 수 있으므로 바람직하지 않을 수 있습니다.

+0

부작용에 대해 설명해 주시겠습니까? 아니면 어떤 사례라도 즐겁습니다. –

+12

예를 들어, 열거 형은 네트워크 스트림에서 바이트를 읽을 수 있습니다 (부작용을 구성 할 수 있음). 한 번 열거하면 모두 괜찮습니다. 한 번에 끝나기 시작하여 스트림을 읽습니다. 그러나 첫 번째 반복을 중단 한 다음 다시 반복하면 기본 네트워크 스트림이 역방향으로 탐색 할 수 없더라도 원치 않는 동작이 발생할 가능성이 높습니다. – tdammers

+0

예를 들어 주셔서 감사합니다 –

8

@tdammers에서 식별하는 것처럼 AnyAll에 의해 요구되는 두 개의 열거 형이 "다중 열거 형"입니다. 빈 시퀀스를 거부하려고하기 때문에 내가 얻을 수있는 최상의 결과는 다음과 같습니다.

public static bool SomeMethod(IEnumerable<string> enumerable) 
{ 
    if (enumerable == null) 
     throw new ArgumentNullException(); 

    // Manually perform an All, keeping track of if there are any elements 
    bool anyElements = false; 

    bool result = true; 

    foreach (string item in enumerable) 
    { 
     anyElements = true; 
     result = result && SomeBooleanMethod(item); 

     // Can short-circuit here 
     if (!result) 
      break; 
    } 

    if (!anyElements) 
     throw new ArgumentException(); // Empty sequence is invalid argument 

    return result; 
} 
+1

노력을 위해 Upvoting. –

관련 문제