44

だから私はstructs のコレクションを持っています(実際にはWCFデータコントラクトですが、これはここでは関係ないと思います)。

List<OptionalExtra> OptionalExtras;

OptionalExtraですstruct

public partial struct OptionalExtra

今、私は以下のステートメントを実行しています:

OptionalExtra multiOptExtra = OptionalExtras.Where(w => w.Code == optExtra.Code).FirstOrDefault();
if (multiOptExtra != null)
{

}

今、これはコンパイルされません:

演算子 != は、タイプ OptionalExtra のオペランドには適用できません。'<null>'

少しグーグルした後、それOptionalExtrastruct. null 許容型として定義されていない限り、どれが null 許容ではないと思いますか?

私の質問は、私のステートメントが結果を返さない場合、呼び出しwhereの結果はどうなるでしょうか? FirstOrDefault例外がスローされますか?

ちなみに、これは決して起こるべきではありませんが、申し訳ありませんが安全です。

4

7 に答える 7

70

コレクションが空の場合、FirstOrDefaultが返されdefault(OptionalExtras)ます。構造体のデフォルト値は、そのすべての値がデフォルトで初期化された構造体です (つまり、ゼロ、null など)。

要素があり、コードが空のコレクションで機能しないと想定している場合は、コレクションが空のときに例外がスローされるため、代わりに使用してください。First()一般に、間違ったデータを返すよりも、すぐに失敗する方がよいでしょう。

要素が存在すると想定できないが、構造体のデフォルトの初期化も処理できない場合は、次のように、コレクション内の構造体をnull 許容値型にすることができます。

OptionalExtras
    .Where(w => w.Code == optExtra.Code)
    .Cast<OptionalExtra?>()
    .FirstOrDefault();

このようにして、構造体に対しても null を返すことができます。ここでの重要なアイデアは、可能な値のセットを拡張して 以外のものを含めOptionalExtra、空のリストを検出できるようにすることです。nullable が気に入らない場合は、代わりにMaybe<>実装 (.NET ビルトインではない) を使用するか、空または単一のリスト (たとえば.Take(1).ToArray()、. ただし、nullable 構造体が最善の策である可能性があります。

TL;DR;

  • .FirstOrDefault<T>()default(T)シーケンスが空の場合に返します
  • .First()リストが空ではないと仮定する場合は、代わりに使用してください。
  • nullable にキャストしてから.FirstOrDefault<T>()、リストが空でないと想定できない場合に使用します。
于 2013-03-14T10:49:05.093 に答える
7

他の人が言ったように、一致する要素がない場合のコードの結果は次のようになります。

default( OptionalExtra )

null を返したい場合は、リストを次のようにキャストできます。OptionalExtra?

OptionalExtra? multiOptExtra = OptionalExtras.Cast<OptionalExtra?>().Where( ...

その後、テストできますnull

于 2013-03-14T10:52:27.330 に答える
4

default(OptionExtra)がまだ有効な値である場合は、コードを次のように変更することをお勧めします

var results = OptionalExtras.Where(w => w.Code == optExtra.Code).Take(1).ToList();
if (results.Any()) {
   multiOptExtra = results[0]
}
于 2013-03-14T10:54:59.007 に答える
3

結果は、構造体のデフォルト値になりますdefault(OptionalExtras)

一方、参照型のデフォルト値は ですnull

于 2013-03-14T10:49:14.127 に答える
2

以下のような構造のデフォルト値を提供します

int[] numbers = { };
int first = numbers.FirstOrDefault();
Console.WriteLine(first);//this print 0 as output 

処理する他のオプションは、以下のようにデフォルト値を利用することです

List<int> months = new List<int> { };
// Setting the default value to 1 by using DefaultIfEmpty() in the query. 
int firstMonth2 = months.DefaultIfEmpty(1).First();
Console.WriteLine("The value of the firstMonth2 variable is {0}", firstMonth2);
于 2013-03-14T10:52:59.513 に答える
0

null を確認する場合は、System.Nullable コレクションを使用します。

var OptionalExtras = new List<OptionalExtra?>();
/* Add some values */
var extras = OptionalExtras.FirstOrDefault(oe => oe.Value.Code == "code");
if (extras != null)
{
    Console.WriteLine(extras.Value.Code);
}

要素にアクセスするには Value を使用する必要があることに注意してください。

于 2015-08-28T06:53:35.817 に答える
-1

コードが私の答えの目的のための文字列であると仮定すると、デフォルトの値をテストするだけでよいはずです。

OptionalExtra multiOptExtra = OptionalExtras.Where(w => w.Code == optExtra.Code).FirstOrDefault();
if (multiOptExtra.Code != null)
{

}
于 2013-08-13T18:22:32.897 に答える