Enumerable.Singleメソッド
【C#】
シーケンスの唯一の要素を返します。シーケンス内の要素が 1 つだけではない場合は、例外をスローします。
public static TSource Single<TSource>
(this IEnumerable<TSource> source)
指定された条件を満たす、シーケンスの唯一の要素を返します。そのような要素が複数存在する場合は、例外をスローします。
public static TSource Single<TSource>
(this IEnumerable source, Func predicate)
【VB】
シーケンスの唯一の要素を返します。シーケンス内の要素が 1 つだけではない場合は、例外をスローします。
<ExtensionAttribute>
Public Shared Function Single(Of TSource)
(source As IEnumerable(Of TSource))
As TSource
指定された条件を満たす、シーケンスの唯一の要素を返します。そのような要素が複数存在する場合は、例外をスローします。
<ExtensionAttribute>
Public Shared Function Single(Of TSource)
(source As IEnumerable(Of TSource), predicate As Func(Of TSource, Boolean))
As TSource
Enumerable.SingleOrDefaultメソッド
【C#】
シーケンスの唯一の要素を返します。シーケンスが空の場合、既定値を返します。
シーケンス内に要素が複数ある場合、このメソッドは例外をスローします。
public static TSource SingleOrDefault<TSource>
(this IEnumerable<TSource> source)
指定された条件を満たす、シーケンスの唯一の要素を返します。そのような要素が存在しない場合、既定値を返します。
複数の要素が条件を満たす場合、このメソッドは例外をスローします。
public static TSource SingleOrDefault<TSource>
(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
【VB】
シーケンスの唯一の要素を返します。シーケンスが空の場合、既定値を返します。
シーケンス内に要素が複数ある場合、このメソッドは例外をスローします。
<ExtensionAttribute>
Public Shared Function SingleOrDefault(Of TSource)
(source As IEnumerable(Of TSource))
As TSource
指定された条件を満たす、シーケンスの唯一の要素を返します。そのような要素が存在しない場合、既定値を返します。
複数の要素が条件を満たす場合、このメソッドは例外をスローします。
<ExtensionAttribute>
Public Shared Function SingleOrDefault(Of TSource)
(source As IEnumerable(Of TSource), predicate As Func(Of TSource, Boolean)) As TSource
シーケンス(配列やコレクションなど)の要素が一つだけのとき、その唯一の要素を取得するメソッドです。
Singleメソッドはシーケンスの要素が一つではないとき(つまりシーケンスの要素が0件または複数件ある状態)例外をスローします。
SingleOrDefaultメソッドはシーケンスの要素が0件のときは、デフォルト値(値型なら初期値、参照型ならnull)を返します。シーケンスの要素が複数のときは、例外をスローします。
このメソッドは即時実行されます。
SingleメソッドとFirstメソッドの使い分けについて
Firstメソッドでも1件の要素を取得することができます。
Firstメソッドは複数要素のシーケンスから、一番最初の要素を取得します。
要素が一つのシーケンスから一番最初の要素を取得すれば、唯一の要素を取得するSingleメソッドと同じ結果にはなります。
しかし後に保守する読み手には「シーケンスの要素は複数件の可能性がある」と読み取れます。
たとえFirstメソッドを使用した結果が同じであっても、シーケンスの要素が必ず1件であるということが明確なときには、Singleメソッドを使用します。
後に保守する読み手に余計な誤解を与えず「シーケンスの要素は1件だけ」ということが明確になります。
テスト用の果物クラスです。
【C#】
private class Fruit
{
public int ID { get; set; }
public string Name { get; set; }
public string Rank { get; set; }
public decimal Price { get; set; }
}
【VB】
Private Class Fruit
Public Property ID As Integer
Public Property Name As String
Public Property Rank As String
Public Property Price As Decimal
End Class
まずはFirsメソッド、FirstOrDefaultメソッドを使用して、唯一の要素を取得します。
リストの要素が1件なので、どちらも問題なく取得できます。
【C#】
//テストデータ
var fruits = new List<Fruit>()
{
new Fruit(){ID = 1, Name = "りんご", Rank = "A" , Price = 1000 }
};
//Singleメソッドを使用して唯一の要素を取得
Fruit fruit1 = fruits.Single();
//出力
Console.WriteLine("ID={0}, 名称={1}", fruit1.ID, fruit1.Name);
//ID=1, 名称=りんご
//SingleOrDefaultメソッドを使用して唯一の要素を取得
Fruit fruit2 = fruits.SingleOrDefault();
//出力
Console.WriteLine("ID={0}, 名称={1}", fruit2.ID, fruit2.Name);
//ID=1, 名称=りんご
【VB】
'テストデータ
Dim fruits = New List(Of Fruit)() From
{
New Fruit() With {.ID = 1, .Name = "りんご", .Rank = "A", .Price = 1000}
}
'Singleメソッドを使用して唯一の要素を取得
Dim fruit1 As Fruit = fruits.Single()
'出力
Console.WriteLine("ID={0}, 名称={1}", fruit1.ID, fruit1.Name)
'ID=1, 名称=りんご
'SingleOrDefaultメソッドを使用して唯一の要素を取得
Dim fruit2 As Fruit = fruits.SingleOrDefault()
'出力
Console.WriteLine("ID={0}, 名称={1}", fruit2.ID, fruit2.Name)
'ID=1, 名称=りんご
次にリストの要素を複数にしてみます。
Singleメソッド、SingleOrDefaultメソッドともにInvalidOperationException例外がスローされます。
【C#】
//テストデータ
var fruits = new List<Fruit>()
{
new Fruit(){ID = 1, Name = "りんご", Rank = "A" , Price = 1000 },
new Fruit(){ID = 2, Name = "みかん", Rank = "A" , Price = 600 }
};
//Singleメソッドを使用して唯一の要素を取得
//例外InvalidOperationExceptionがスローされる
Fruit fruit1 = fruits.Single();
//SingleOrDefaultメソッドを使用して唯一の要素を取得
//例外InvalidOperationExceptionがスローされる
Fruit fruit2 = fruits.SingleOrDefault();
【VB】
'テストデータ
Dim fruits = New List(Of Fruit)() From
{
New Fruit() With {.ID = 1, .Name = "りんご", .Rank = "A", .Price = 1000},
New Fruit() With {.ID = 2, .Name = "みかん", .Rank = "A", .Price = 600}
}
'Singleメソッドを使用して唯一の要素を取得
'例外InvalidOperationExceptionがスローされる
Dim fruit1 As Fruit = fruits.Single()
'Singleメソッドを使用して唯一の要素を取得
'例外InvalidOperationExceptionがスローされる
Dim fruit2 As Fruit = fruits.SingleOrDefault()
次はリストの要素を0件にしてみます。
SingleメソッドはInvalidOperationException例外がスローされますが
SingleOrDefaultメソッドでは、参照型の規定値であるnullが返ります。
【C#】
//テストデータ
var fruits = new List<Fruit>();
//Singleメソッドを使用して唯一の要素を取得
//例外InvalidOperationExceptionがスローされる
Fruit fruit1 = fruits.Single();
//SingleOrDefaultメソッドを使用して唯一の要素を取得
//参照型なのでnullが返る
Fruit fruit2 = fruits.SingleOrDefault();
//出力
Console.WriteLine(fruit2 == null ? "null" : fruit2.Name);
//null
【VB】
'テストデータ
Dim fruits = New List(Of Fruit)()
'Singleメソッドを使用して唯一の要素を取得
'例外InvalidOperationExceptionがスローされる
Dim fruit1 As Fruit = fruits.Single()
'SingleOrDefaultメソッドを使用して唯一の要素を取得
'参照型なのでnullが返る
Dim fruit2 As Fruit = fruits.SingleOrDefault()
'出力
Console.WriteLine(If(fruit2 Is Nothing, "nothing", fruit2.Name))
'nothing
Singleメソッド、SingleOrDefaultメソッドには、抽出条件を指定できるオーバーロードメソッドがあります。
条件に該当するデータが1件(または0件)となるような抽出条件を指定します。
抽出条件に該当するデータが複数件の場合、Singleメソッド、SingleOrDefaultメソッドともに例外をスローします。
抽出条件に該当するデータが0件の場合、Singleメソッドは例外をスローし、SingleOrDefaultメソッドは規定値を返します。
【C#】
//テストデータ
var fruits = new List<Fruit>()
{
new Fruit(){ID = 1, Name = "りんご", Rank = "A" , Price = 1000 },
new Fruit(){ID = 2, Name = "みかん", Rank = "A" , Price = 600 },
new Fruit(){ID = 3, Name = "ぶどう", Rank = "B" , Price = 1200 },
new Fruit(){ID = 4, Name = "りんご", Rank = "B" , Price = 800 },
new Fruit(){ID = 5, Name = "みかん", Rank = "A" , Price = 500 }
};
//Singleメソッドを使用して唯一の要素を取得
Fruit fruit1 = fruits.Single(itm => itm.ID == 3);
//出力
Console.WriteLine("ID={0}, 名称={1}", fruit1.ID, fruit1.Name);
//ID=3, 名称=ぶどう
//SingleOrDefaultメソッドを使用して唯一の要素を取得
Fruit fruit2 = fruits.SingleOrDefault(itm => itm.ID == 3);
//出力
Console.WriteLine("ID={0}, 名称={1}", fruit2.ID, fruit2.Name);
//ID=3, 名称=ぶどう
【VB】
'テストデータ
Dim fruits As New List(Of Fruit)() From
{
New Fruit() With {.ID = 1, .Name = "りんご", .Rank = "A", .Price = 1000},
New Fruit() With {.ID = 2, .Name = "みかん", .Rank = "A", .Price = 600},
New Fruit() With {.ID = 3, .Name = "ぶどう", .Rank = "B", .Price = 1200},
New Fruit() With {.ID = 4, .Name = "りんご", .Rank = "B", .Price = 800},
New Fruit() With {.ID = 5, .Name = "みかん", .Rank = "A", .Price = 500}
}
'Singleメソッドを使用して唯一の要素を取得
Dim fruit1 As Fruit = fruits.Single(Function(itm) itm.ID = 3)
'出力
Console.WriteLine("ID={0}, 名称={1}", fruit1.ID, fruit1.Name)
'ID=3, 名称=ぶどう
'SingleOrDefaultメソッドを使用して唯一の要素を取得
Dim fruit2 As Fruit = fruits.SingleOrDefault(Function(itm) itm.ID = 3)
'出力
Console.WriteLine("ID={0}, 名称={1}", fruit2.ID, fruit2.Name)
'ID=3, 名称=ぶどう
※VBの場合、コンパイルオプションで「Option Infer」をONにし、型推論を有効にしてください。
.Net(VB C#) LINQのメソッド一覧
0 件のコメント:
コメントを投稿