VB.NET Использовать ключевое слово With для существующего объекта?

StackOverflow https://stackoverflow.com/questions/2511985

Вопрос

Можно ли как-то использовать ключевое слово With для существующего объекта?

Я хотел бы сделать следующее, используя LINQ для объектов, и, похоже, не могу найти способ:

From m as Product in Me _
  Select m With {.Match = m.Name.IndexOf(query)} _ 
  Where m.Name.IndexOf(query) > 0
Это было полезно?

Решение

Нет, нет никакого способа сделать это (With может использоваться только с конструктором). Это нарушит функциональные принципы, на которых строится LINQ, в частности, что не будет побочных эффектов.

Лучше всего создать новый продукт в своем выборе с набором свойств совпадений.

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 _
              } 

Другие советы

В vb.net есть два использования ключевого слова With.

Первым является инициализация объекта. Это средство назначения свойств или полей объекта в той же линии, что и выражение инициализации без необходимости конкретного конструктора для каждой перестановки полей.

Dim x = New Product With {.Name = "Foo"}

Этот тип выражения может использоваться только для создания новых объектов. Он не может быть использован для изменения существующих.

Второе использование - это With утверждение. Это позволяет вам поместить объект в контекст, так сказать, и позвонить многим. операции на нем без квалификации.

With x
    Console.WriteLine(.Name)
    .Match = 42
End With

Ни один из них не позволит вам использовать существующий объект в качестве шаблона для создания нового объекта.

Нет. Проблема в том, что With Ключевое слово (ключевое слово инициализации объекта, а не оператор) может использоваться только после создания нового объекта.

Команда VB думает что побочные эффекты использования With На существующем объекте будет слишком запутанным.

О вашей проблеме: если Match еще не является собственностью Product, самое чистое решение может состоять в том, чтобы инкапсулировать требуемый выход в новый объект:

From m as Product in Me _
  Select New With {.Match = m.Name.IndexOf(query), .Product = m} _ 
  Where m.Name.IndexOf(query) > 0

С включенным методом расширения System.Object который принимает лямбду, вы можете довольно точно смоделировать такую ​​функцию. В этом ответе есть пример, но это на C#.Вероятно, это не так уж и сложно перевести на VB.NET.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top