LINQ
- Usando os métodos Single e SingleOrDefault
![]() |
O LINQ possui o método de extensão Single que pode ser usado para retornar somente um elemento em uma sequência que satisfaça uma condição específica. |
Nota: Para saber mais sobre métodos de extensão veja o artigo: VB.NET - Extensions Methods
O problema é que o método Single irá lançar uma exceção do tipo System.InvalidOperationException quando nenhum elemento na sequência satisfazer a condição que foi definida.
![]() |
Para contornar este problema você pode usar o método de extensão SingleOrDefault que vai retornar o valor padrão do tipo ao invés de lançar a exceção quando nenhum elemento satisfazer a condição.
Agora, preste atenção, se mais de um elemento na sequência satisfazer a condição ambos os métodos irão lançar a exceção System.InvalidOperationException e neste caso você pode apelar para os métodos de extensão First ou Last.
Nota: Geralmente usamos estes métodos de extensão em expressões lambda.
![]() As expressões lambda foram incluídas no VS/VB 2008 para dar suporte a consultas LINQ. As cláusulas Where são assim compiladas como expressões lambdas e chamadas em itens aplicáveis do seu dataset. Podem ser consideradas uma forma de delegate que pode passar ou retornar outra função. Nota: Delegates permitem que uma classe use métodos de outra classe. Para saber mais sobre delegates leia o meu artigo: Usando Delegates No LINQ as expressões lambda são usadas para realizar ações sobre listas de objetos e com métodos de extensão. Uma expressão lambda é então uma função sem nome que calcula e retorna um valor único e podem ser usadas em qualquer lugar que um tipo delegate for válido. |
Vejamos isso na prática: ( criado no Visual Basic 2008 Express Edition aplicação do tipo console:)
Module Module1 Sub Main() ' Cria uma lista genérica de inteiros Dim l0 As New List(Of Integer) 'Inclui mais elementos a lista l0.Add(11) ' l0.Add(15) l0.Add(13) l0.Add(17) Try ' Retorna somente o resultado 11 pois somente ele satisfaz a condição (i=11) Dim resultado As Integer = l0.Single(Function(i) i = 11) Console.WriteLine("Elemento igual a 11 => " & resultado) Console.ReadKey() ' Retorna o valor padrão para os inteiros que é zero ' pois nenhum elemento na lista é igual a 14 resultado = l0.SingleOrDefault(Function(i) i = 14) Console.WriteLine("Elemento igual a 14 (SingleOrDefault) => " & resultado) Console.ReadKey() ' lança a exceção System.InvalidOperationException ' pois nenhum elemento na lista é igual a 14 resultado = l0.Single(Function(i) i = 14) Console.WriteLine("Elemento igual a 14 (Single) => " & resultado) Console.ReadKey() ' lança a exceção System.InvalidOperationException ' pois temos dois elementos(15 e 17) maiores que 13 resultado = l0.Single(Function(i) i > 13) Console.WriteLine("Elemento maior que 13 (Single) => " & resultado) Console.ReadKey() resultado = l0.SingleOrDefault(Function(i) i > 13) Console.WriteLine("Elemento maior que 13 (SingleOrDefault) => " & resultado) Catch ex As Exception Console.WriteLine("Erro : " & ex.Message) End Try Console.ReadKey() End Sub End Module |
Quando temos mais de um elemento na sequência, para contornar a exceção que seria lançada você pode usar o método de extensão para retornar o primeiro elemento que satifaz a condição:
resultado = l0.First(Function(i) i > 13)
ou o último elemento:
resultado = l0.Last(Function(i) i > 13)
O mesmo código para C# ficaria assim: (Pode ser usando no Visual C# Express Edition ou no SharpDevelop 3.0)
public static void Main(string[] args) { Console.WriteLine("Usando Single ou SingleOrDefault"); // Cria uma nova lista generica de inteiros List<int> 10 = new List<int>(); //inclui mais inteiros a lista l0.Add(12); l0.Add(15); l0.Add(13); 10.Add(17); // Retorna o valor 10 pois somente 10 satisfaz a condição int resultado = l0.Single(i => i == 10); Console.Write("valor = " + resultado); // Retorna o valor padrão que para os inteiros é zero // pois nenhum elemento na lista é igual a 14 resultado = l0.SingleOrDefault(i => i == 14); Console.Write("valor = " + resultado); // lança a execção System.InvalidOperationException // pois nenhum elemento na lista é igual a 14 resultado = l0.Single(i => i == 14); Console.Write("valor = " + resultado); // lança a exeção System.InvalidOperationException // pois temos dois elementos, 15 e 17 que são maiores que 13 resultado = l0.Single(i => i > 13); Console.Write("valor = " + resultado); resultado = l0.SingleOrDefault(i => i > 13); Console.Write("valor = " + resultado); Console.Write("Pressiona algo para continuar . . . "); Console.ReadKey(true); } |
Aguarde mais artigos sobre LINQ.
Referências:
José Carlos Macoratti