제공된 값이 목록의 값과 일치하는지 확인하려는 경우가 있습니다 (예 : 유효성 검사시).
if (!acceptedValues.Any(v => v == someValue))
{
// exception logic
}
최근 ReSharper가 다음과 같은 쿼리를 단순화하도록 요청했습니다.
if (acceptedValues.All(v => v != someValue))
{
// exception logic
}
분명히 이것은 논리적으로 동일하며 약간 더 읽기 쉽습니다 (많은 수학을 한 경우), 내 질문은 : 이것이 성능 저하를 초래합니까?
그것은 마치 느낌이 들지만 (즉 .Any()
, 단락되는 .All()
것처럼 들리지만 소리는 들리지 않습니다), 나는 이것을 입증 할 것이 없습니다. 쿼리를 통해 동일한 문제를 해결할지 또는 ReSharper가 나를 타락시키는 지에 대해 더 깊이 알고 있습니까?
답변
All
ILSpy 에 따른 구현 (실제로 “잘, 그 방법은 약간 비슷하게 작동하는 것”보다는 실제로 갔다가 보았 기 때문에 영향보다는 이론을 논의하는 경우에 할 수있다).
public static bool All<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
if (source == null)
{
throw Error.ArgumentNull("source");
}
if (predicate == null)
{
throw Error.ArgumentNull("predicate");
}
foreach (TSource current in source)
{
if (!predicate(current))
{
return false;
}
}
return true;
}
Any
ILSpy 에 따라 구현 :
public static bool Any<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
if (source == null)
{
throw Error.ArgumentNull("source");
}
if (predicate == null)
{
throw Error.ArgumentNull("predicate");
}
foreach (TSource current in source)
{
if (predicate(current))
{
return true;
}
}
return false;
}
물론, 생성 된 IL에는 약간의 미묘한 차이가있을 수 있습니다. 그러나 아닙니다. IL은 거의 동일하지만 술어 일치시 true를 리턴하는 것과 술어 불일치시 false를 리턴하는 것의 명백한 역전을 나타냅니다.
이것은 물론 linq-for-objects입니다. 다른 linq 제공자는 다른 linq 제공자가 다른 것보다 하나를 훨씬 잘 처리 할 수 있지만,이 경우 더 최적의 구현을 가진 것은 무작위입니다.
이 규칙 if(determineSomethingTrue)
은보다 단순하고 읽기 쉬운 사람에게만 적용되는 것 같습니다 if(!determineSomethingFalse)
. 그리고 공정성에서, 나는 그들이 if(!someTest)
우리가 행동하고자하는 조건에 대해 진실로 되돌아 갈 수있는 동등한 상세 성과 복잡성에 대한 대안적인 테스트가있을 때 종종 혼란스러워 한다는 점을 생각 합니다. 그러나 실제로, 나는 개인적으로 당신이 제공하는 두 가지 대안 중 하나를 선호하는 것을 찾지 못하며, 술어가 더 복잡하다면 아마도 전자에게 약간 기울어 질 것입니다.
* 나는 이해하지 못하는 것처럼 혼란스럽지 않지만, 나는 이해하지 못하는 결정에 미묘한 이유가 있다고 걱정하고, “아니, 그들은 단지 그런 식으로 기다렸다가 다시이 코드를보고 있던 것이 무엇입니까? … “
답변
이러한 확장 방법을 사용하면 코드를 더 읽기 쉽게 만들 수 있습니다.
public static bool None<TSource>(this IEnumerable<TSource> source)
{
return !source.Any();
}
public static bool None<TSource>(this IEnumerable<TSource> source,
Func<TSource, bool> predicate)
{
return !source.Any(predicate);
}
이제 원래 대신
if (!acceptedValues.Any(v => v == someValue))
{
// exception logic
}
넌 말할 수있다
if (acceptedValues.None(v => v == someValue))
{
// exception logic
}
답변
– 둘 다 결과 후 모두 정지 열거 판단 할 수 있기 때문에 동일한 성능 것이다 Any()
첫 번째 항목에 전달 된 술어 평가합니다로 true
와 All()
의 술어 평가하여 첫 번째 항목에를 false
.
답변
All
첫 번째 비 일치에 단락이 발생하므로 문제가되지 않습니다.
미묘의 한 영역은
bool allEven = Enumerable.Empty<int>().All(i => i % 2 == 0);
사실이다. 시퀀스의 모든 항목이 균일합니다.
이 방법에 대한 자세한 내용은 Enumerable.All 설명서를 참조하십시오 .
답변
All()
시퀀스의 모든 요소가 조건을 만족하는지 여부를 결정합니다.
Any()
시퀀스의 요소가 조건을 만족하는지 여부를 결정합니다.
var numbers = new[]{1,2,3};
numbers.All(n => n % 2 == 0); // returns false
numbers.Any(n => n % 2 == 0); // returns true
답변
이 링크 에 따르면
모두 – 하나 이상의 일치를 확인합니다
모두 – 모두 일치하는지 확인
답변
다른 답변에서 잘 설명했듯이 성능에 관한 것이 아니라 명확성에 관한 것입니다.
두 옵션 모두에 대해 광범위하게 지원됩니다.
if (!acceptedValues.Any(v => v == someValue))
{
// exception logic
}
if (acceptedValues.All(v => v != someValue))
{
// exception logic
}
그러나 이것이 더 광범위한 지원을 얻을 수 있다고 생각 합니다 .
var isValueAccepted = acceptedValues.Any(v => v == someValue);
if (!isValueAccepted)
{
// exception logic
}
부울을 계산하기 전에 부울을 계산하고 이름을 지정하는 것만으로도 내 마음에 이것을 많이 알 수 있습니다.
