VB.NET Use com palavra -chave no objeto existente?
-
22-09-2019 - |
Pergunta
De alguma forma, é possível usar a palavra -chave 'com' em um objeto existente?
Eu gostaria de fazer o seguinte usando o LINQ para objetos e não consigo encontrar uma maneira:
From m as Product in Me _
Select m With {.Match = m.Name.IndexOf(query)} _
Where m.Name.IndexOf(query) > 0
Solução
Não, não há como fazer isso (With
só pode ser usado com um construtor). Isso violaria os princípios funcionais sobre os quais o LINQ é construído, especificamente que não haverá efeitos colaterais.
A melhor aposta é criar um novo produto em sua seleção com o conjunto de propriedades Match.
From m as Product in Me _
Where m.Name.IndexOf(query) > 0 _
Select New Product() With _
{ _
.Match = m.Name.IndexOf(query), _
...apply the rest of m's properties _
}
Outras dicas
No vb.net, existem dois usos da palavra -chave With
.
O primeiro é a inicialização do objeto. É um meio de atribuir propriedades ou campos de um objeto na mesma linha que uma expressão de inicialização sem a necessidade de um construtor específico para cada permutação dos campos.
Dim x = New Product With {.Name = "Foo"}
Esse tipo de expressão pode ser usado apenas para criar novos objetos. Não pode ser usado para modificar os existentes.
O segundo uso é o With
declaração. Isso permite que você coloque um objeto em contexto, por assim dizer e ligar para muitos. operações nele sem qualificação.
With x
Console.WriteLine(.Name)
.Match = 42
End With
Nenhum deles permitirá que você use um objeto existente como modelo para criar um novo objeto.
Não. O problema é que o With
palavra -chave (a palavra -chave de inicialização do objeto, não a instrução) só pode ser usada após a criação de um novo objeto.
A equipe VB pensa que os efeitos colaterais do uso With
em um objeto existente seria muito confuso.
Sobre o seu problema: se Match
ainda não é uma propriedade de Product
, a solução mais limpa pode ser encapsular a saída necessária em um novo objeto:
From m as Product in Me _
Select New With {.Match = m.Name.IndexOf(query), .Product = m} _
Where m.Name.IndexOf(query) > 0
Com um método de extensão em System.Object
Isso aceita um lambda, você pode simular esse recurso de perto. Há um exemplo nesta resposta, mas está em C#. Provavelmente não é muito difícil traduzir para o vb.net.