私が理解しているように、Linq では、メソッドはnull 以外FirstOrDefault()
の値を返すことができます。Default
私が解決していないのは、クエリ結果にアイテムがない場合に、この (および同様の) メソッドによって null 以外にどのようなものが返されるかということです。特定のクエリに値がない場合、事前定義された値がデフォルト値として返されるように設定できる特定の方法はありますか?
14 に答える
私が理解しているように、Linq では、FirstOrDefault() メソッドは null 以外の Default 値を返すことができます。
いいえ、むしろ、要素型のデフォルト値を常に返します...これは、null参照、null許容値型のnull値、またはnull非許容値型の自然な「すべてゼロ」値のいずれかです。
特定のクエリに値がない場合、事前定義された値がデフォルト値として返されるように設定できる特定の方法はありますか?
参照型の場合は、次を使用できます。
var result = query.FirstOrDefault() ?? otherDefaultValue;
もちろん、最初の値が存在するがnull参照である場合、これは「他のデフォルト値」も提供します...
DefaultIfEmptyの後にFirstを使用できます。
T customDefault = ...;
IEnumerable<T> mySequence = ...;
mySequence.DefaultIfEmpty(customDefault).First();
値型だけでなく、一般的なケース:
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()
.
FirstOrDefaultのドキュメントから
[戻り値] ソースが空の場合は default(TSource)。
default(T)のドキュメントから:
デフォルトのキーワード。参照型の場合は null を返し、数値型の場合は 0 を返します。構造体の場合は、構造体の各メンバーが値型か参照型かに応じて、ゼロまたは null に初期化されて返されます。null 許容値型の場合、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!
DefaultIfEmpty()
の代わりに使用しFirstOrDefault()
ます。