C # List <>에서 .Any ()를 사용하는 것은 무엇입니까?


40

나는 이것을 동료들과 논의 하고 있으며 C #에서 .Any어떤 용도로 사용되는지 알 수 없었습니다 List<>.

다음 명령문과 같이 배열에서 요소의 유효성을 확인할 수 있습니다.

if (MyList.Any()){ ...}  //Returns true or false

정확히 같은

if (MyList.Count() != 0) { ... }

그리고 if성명서 의 의도에 대해 훨씬 더 일반적이고 읽기 쉽고 명확 합니다.

결국 우리는이 생각에 갇혀있었습니다.

.Any() 사용할 수 있고, 잘 작동하지만 프로그래머의 의도에 대해서는 명확하지 않으며,이 경우에는 사용해서는 안됩니다.

그러나 우리는 이것이 옳지 않다고 생각합니다. 우리는 무언가를 놓치고 있어야합니다.

우리는?


40
어떤면에서 의도가 덜 명확합니까?
jk.

35
나는 Any()덜 분명한 당신의 주장에 도전합니다 . Any()특히 람다 상태에서 더 명확 해 보입니다. 머리에서 영어로 코드를 번역 if(MyList.Count(o => o > 10) > 0)하면 "10보다 큰 항목 수가 0보다 큽니까?"가됩니다. 반면 if(MyList.Any(o => o > 10))된다 "이 모든 항목은 10보다 큰?"
BlueRaja-대니 Pflughoeft

3
@SargeBorsch-대부분의 사람들이 원하지 않는 Heskel / 기능 명을 선호하는 경우에만.
Davor Ždralo

4
@ BlueRaja-DannyPflughoeft 동의합니다. 나는 그것이 마법의 숫자로 간주 될 수있는 것을 제거하기 때문에 더 분명하다고 생각합니다.
Andy

2
@SargeBorsch :에 대한 SQL AnyExists입니다. Linq 이름은 아마도 모든 기능을 가진 Haskell과 Python에서 더 영감을 얻었습니다.
JacquesB

답변:


95

;에서 Any작동하지 않는 것을 명심하십시오 List; 속성을 IEnumerable가질 수도 있고 갖지 않을 수도있는 구체적인 유형을 나타내는에서 작동 Count합니다. 에 사용하는 것이 가장 좋은 것은 List아니지만 LINQ 쿼리가 끝날 때 확실히 유용합니다. 그리고 독립형 버전보다 훨씬 더 유용한 것은 마치 술어를 취하는 재정의입니다 Where. List술어 Any확장 방법 만큼 편리하거나 표현적인 곳에 는 아무것도 내장되어 있지 않습니다 .

또한 (on 속성 Count()) 대신 Count( IEnumerable에 대한 LINQ 확장 방법)을 사용하는 경우 기본 데이터 유형에 속성 이 있음을 감지하여이를 최적화 할 수 없으면List 전체 시퀀스를 열거 해야 할 수 있습니다Count . 당신이 긴 순서가있는 경우, 이것은 당신이 정말 카운트가 무엇인지에 대해 걱정하지 않는다 눈에 띄는 성능 저하, 그리고 바로이 있는지 알고 싶어 할 수 있는 컬렉션의 항목.


19
이. Any()술어가있는 성능 은 술어를 사용 하는 재정의 를 0과 비교하는 것보다 표현력이 Enumerable.Count()
Dan J

1
나는 이것이 기본을 매우 명확하게 설명한다고 생각합니다.
Tarik

2
IMHO 는 술어와 Exists마찬가지로 편리하고 표현력 Any이 뛰어납니다. 에서 Count != 0속성을 사용 하는 List것이를 사용 하는 것보다 더 일반적 Any()입니다. 개인적인 취향 일뿐입니다. 나는 또한 변화의 노력을 겪었어요 _list_.Count()_list_.Count내 그룹의 코드. 그것은 나에게 눈에 띄는 차이를 만들었습니다.
Suncat2000

55

런타임 차이 Count()는 O (n) 일 수 있으며 여기서 Any()O (1)입니다.


15
Count()또한 한 번만 Any()호출 MoveNext()하면 되므로 무한 반복자는 중단되지 않습니다 .
Jon Purdy

3
간결하고 정확하지만 답변보다 주석으로 더 많이 읽습니다. 프로그래머는 이유 를 설명하고 설명을 제공하는 답변을 선호합니다 . 답을 수정 하고 왜 O (1)이 중요한지에 대해 생각해보십시오 .

D : 아주 좋은 대답은 내가 대신 카운트 == 0의 사용해야 배운
MonsterMMORPG

4
Any(Func<T>)is O (n)
BlueRaja-Danny Pflughoeft

1
의 경우 List확장에서 속성을 사용하므로 성능이 동일합니다. ICollection인터페이스를 구현하는 모든 컬렉션에 적용 됩니다.
Thorkil Holm-Jacobsen

9

실제로 List.Count 속성이 있고 Enumerable.Count 메서드 가 있다는 것을 명심 하십시오 .

예제에서 Enumerable.Count()메소드를 사용하고 있습니다.이 메소드는 열거 형의 모든 단일 항목을 반복하여 결과를 리턴해야합니다. 그것은 Any()첫 번째 항목이 있으면 반복 해야하는 호출보다 분명히 느립니다 .

편집하다:

주석에서 올바르게 지적되었으므로 Enumerable.Count()열거 형이 열거 형 인 것으로 감지되면 확장 방법이 모든 항목을 반복 할 필요가 없습니다 ICollection<T>. 따라서의 경우 속성이나 메서드를 List<T>사용하면 Count실제로 차이가 없습니다.

IEnumerable. 카운트 소스 :

public static int Count<TSource>(this IEnumerable<TSource> source) {
    if (source == null) throw Error.ArgumentNull("source");
    ICollection<TSource> collectionoft = source as ICollection<TSource>;
    if (collectionoft != null) return collectionoft.Count;
    ICollection collection = source as ICollection;
    if (collection != null) return collection.Count;
    int count = 0;
    using (IEnumerator<TSource> e = source.GetEnumerator()) {
        checked {
            while (e.MoveNext()) count++;
        }
    }
    return count;
}

그럴 수 있지. 그러면 .Count 속성을 사용하는 것은 어떻습니까? .Any ()를 호출하는 것보다 훨씬 빠르거나 빠를 수도 있습니다.
Gil Sand

4
A의 List<T>성능 차이는 무시할 수있을 것입니다. 따라서 원하는 것을 사용하십시오. 그러나 다른 유형의 IEnumerables의 경우 Count()(방법) 중 하나만 선택할 수 있으며이 Any()경우 Any()항상 유스 케이스에서 확실한 승자가 될 것이므로 선호해야합니다. 그만한 가치가 있다고 생각 Any()합니다.
sstan

ienumerable이 collention으로 캐스팅 될 수 없다면 @sstan yes가 최적화 될 수 있고 중요하지 않습니다.
Esben Skov Pedersen

2
Count()동일한 복잡성 갖는다 Count위한 ICollection확장 방법은 다음 반복하는 대신 속성을 사용하므로들.
Thorkil Holm-Jacobsen

Linq 확장은 알려진 인터페이스 (IList, ICollection)에 최적화되어 있습니다. 여기에서 성능에 대한 논의는 구현 세부 사항이더라도 완전히 중복됩니다
Gusdor

6

놀라운 질문-나는 의도 list.Any()보다 의도가 훨씬 더 명확하다는 것을 알았습니다 list.Count()!=0.

의도의 의미 : 누군가의 코드를 읽고 (직접 작성하지 않은 경우) 프로그래머가 달성하고자하는 것이 무엇인지, 왜 그렇게 작성되었는지는 분명합니까? 일반적인 문제가 불필요하게 복잡한 방식으로 해결되면 즉시 의심스럽고 개발자가 왜 간단한 방법을 사용하지 않았는지 궁금해합니다. 코드를 살펴보고 무언가를 놓쳤는 지 확인하십시오. 누락 된 부작용이 있으며 코드를 변경하면 예기치 않은 문제가 발생할 수 있으므로 코드를 변경해야합니다.

Any()방법 을 사용하려는 의도는 명확합니다. 목록에 요소가 있는지 여부를 알고 싶습니다.

Count()!=0반면에 표현의 의도 는 독자에게는 분명하지 않습니다. 물론 표현식이 목록이 비어 있는지 아닌지를 알려주는 것은 어렵지 않습니다. 표준 방법을 사용하지 않고 이러한 방식으로 작성하기 때문에 문제가 발생합니다. 왜 Count()명시 적으로 사용 합니까? 당신은 정말이 있는지 알고 싶다면 어떤 목록의 요소, 왜 먼저 전체 목록을 계산 하시겠습니까? 당신이 1에 도달하자마자 당신은 이미 답을 얻었습니다. 소스가 큰 (아마도 무한한) 컬렉션의 반복자이거나 sql로 변환 된 경우 성능면에서 큰 차이를 만들 수 있습니다. 아마도 Count ()의 명시 적 사용은 지연 된 쿼리가 반복자를 실행하거나 통과하도록 강제하는 것입니까?

그러나 실제로 소스이며 List<T>여기서 Count()O (1)이며, 부작용이 없다. 그러나 코드가의이 속성에 의존하는 경우 부작용없이 O (1) 연산을 기대한다는 것을보다 명확하게 나타내는 -property를 List<T>사용하지 않는 이유 Count는 무엇입니까?

그것이 쓰여질 때, 불필요하게 더 복잡하고 의도가 불분명하다는 것을 제외하고 list.Count()!=0는 정확히 동일 list.Any()합니다.


"목록에 항목이 포함되어 있습니까?" Count()사용을 피할 수있는 암시 적 변환이 있지만 명확하지 않습니다. 컴파일러는이를 최적화하여 부주의 한 코딩 만 할 수 있습니다.
Suncat2000

2

어쩌면 단어일까요? Any실제로 아무 말도하지 않는 형용사입니다. Java에서 온 isNonEmpty동사를 포함하는 것으로 부릅니다 . SQL 녀석은 선호 할지도 모른다EXISTS . 그러나 AnyC # 시스템에 가장 적합 할 수 있습니다.

단어 선택이 무엇이든, 일단 익숙해지면 훨씬 분명 해야합니다 . " more than zero맥주병이 남아 있습니까? " 당신은 기대 one or more그들은 "아니,이없는 대답하기 전에 계산하기 시작 사람 any?"


1
당신이 LINQ의 관점에서 생각하면 이름은 "어떤"의미가 있습니다 : Any()바로 가기는 정말Any(o => true)
BlueRaja - 대니 Pflughoeft

열거 형이 열거 할 수 있는지를 설명하기 위해 일반적으로 empty를 사용하지는 않습니다. 그러나 "열어야 것이 있습니까?"는 자연스럽고 모든 열거에 대해 작동합니다.
Andy
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.