내가 이해하는 것처럼 Linq에서 메소드 FirstOrDefault()
는 Default
null 이외 의 값을 반환 할 수 있습니다 . 내가 해결하지 않은 것은 쿼리 결과에 항목이 없을 때 null (이와 비슷한) 메소드로 null 이외의 다른 유형을 반환 할 수 있다는 것입니다. 특정 쿼리에 대한 값이없는 경우 미리 정의 된 일부 값이 기본값으로 반환되도록 설정할 수있는 특정 방법이 있습니까?
답변
값 유형이 아닌 일반적인 경우 :
static class ExtensionsThatWillAppearOnEverything
{
public static T IfDefaultGiveMe<T>(this T value, T alternate)
{
if (value.Equals(default(T))) return alternate;
return value;
}
}
var result = query.FirstOrDefault().IfDefaultGiveMe(otherDefaultValue);
다시 말하지만, 시퀀스 에 어떤 것이 있는지 또는 첫 번째 값이 기본값 인지 알 수 없습니다 .
당신이 이것에 관심이 있다면, 당신은 같은 것을 할 수 있습니다
static class ExtensionsThatWillAppearOnIEnumerables
{
public static T FirstOr<T>(this IEnumerable<T> source, T alternate)
{
foreach(T t in source)
return t;
return alternate;
}
}
로 사용
var result = query.FirstOr(otherDefaultValue);
Steak 씨가 지적했듯이 이것은 이것에 의해서도 가능 .DefaultIfEmpty(...).First()
합니다.
답변
내가 이해하는 것처럼 Linq에서 FirstOrDefault () 메소드는 null 이외의 기본값을 반환 할 수 있습니다.
또는 요소 유형의 기본값을 항상 리턴합니다. 이는 널 참조, 널 입력 가능 값 유형의 널 (NULL) 값 또는 널 입력 불가능 값 유형의 자연 “모든 0″값입니다.
특정 쿼리에 대한 값이없는 경우 미리 정의 된 일부 값이 기본값으로 반환되도록 설정할 수있는 특정 방법이 있습니까?
참조 유형의 경우 다음을 사용할 수 있습니다.
var result = query.FirstOrDefault() ?? otherDefaultValue;
물론 첫 번째 값이 존재하지만 null 참조 인 경우 “기타 기본값” 도 제공합니다 …
답변
DefaultIfEmpty 다음에 First를 사용할 수 있습니다 .
T customDefault = ...;
IEnumerable<T> mySequence = ...;
mySequence.DefaultIfEmpty(customDefault).First();
답변
FirstOrDefault 문서에서
소스가 비어 있으면 [Returns] default (TSource);
default (T)에 대한 문서에서 :
기본 키워드. 참조 유형의 경우 null을, 숫자 값 유형의 경우 0을 반환합니다. 구조체의 경우 구조체의 값 또는 참조 유형에 따라 0 또는 null로 초기화 된 구조체의 각 멤버를 반환합니다. nullable 값 형식의 경우 default는 모든 구조체와 같이 초기화되는 System.Nullable을 반환합니다.
따라서 유형이 참조인지 또는 값 유형인지에 따라 기본값은 null 또는 0 일 수 있지만 기본 동작은 제어 할 수 없습니다.
답변
@sloth의 코멘트에서 복사 함
대신에 예를 들어 YourCollection.FirstOrDefault()
사용할 수 있습니다 YourCollection.DefaultIfEmpty(YourDefault).First()
.
예:
var viewModel = new CustomerDetailsViewModel
{
MainResidenceAddressSection = (MainResidenceAddressSection)addresses.DefaultIfEmpty(new MainResidenceAddressSection()).FirstOrDefault( o => o is MainResidenceAddressSection),
RiskAddressSection = addresses.DefaultIfEmpty(new RiskAddressSection()).FirstOrDefault(o => !(o is MainResidenceAddressSection)),
};
답변
당신은 또한 이것을 할 수 있습니다
Band[] objects = { new Band { Name = "Iron Maiden" } };
first = objects.Where(o => o.Name == "Slayer")
.DefaultIfEmpty(new Band { Name = "Black Sabbath" })
.FirstOrDefault(); // returns "Black Sabbath"
이것은 linq만을 사용합니다-yipee!
답변
실제로 NullReferenceException
컬렉션 을 사용할 때 피하기 위해 두 가지 접근 방식을 사용합니다 .
public class Foo
{
public string Bar{get; set;}
}
void Main()
{
var list = new List<Foo>();
//before C# 6.0
string barCSharp5 = list.DefaultIfEmpty(new Foo()).FirstOrDefault().Bar;
//C# 6.0 or later
var barCSharp6 = list.FirstOrDefault()?.Bar;
}
C # 6.0 이상의 경우 :
사용 ?.
또는 ?[
테스트에 널 (null)이 전 멤버 액세스를 수행하는 경우 널 조건부 연산자 문서
예:
var barCSharp6 = list.FirstOrDefault()?.Bar;
C # 이전 버전 :
DefaultIfEmpty()
시퀀스가 비어있는 경우 기본값을 검색하는 데 사용 합니다. MSDN 설명서
예:
string barCSharp5 = list.DefaultIfEmpty(new Foo()).FirstOrDefault().Bar;