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 Any은 Exists입니다. 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.