views:

174

answers:

4

Is it somehow possible to use the 'With' keyword on an existing object?

I would like to do the following using LINQ to objects and can't seem to find a way:

From m as Product in Me _
  Select m With {.Match = m.Name.IndexOf(query)} _ 
  Where m.Name.IndexOf(query) > 0
+1  A: 

No. The problem is that the With keyword (the object initialization keyword, not the statement) can only be used after creating a new object.

The VB team thinks that the side-effects of using With on an existing object would be too confusing.

About your problem: If Match is not yet a property of Product, the cleanest solution might be to encapsulate the required output in a new object:

From m as Product in Me _
  Select New With {.Match = m.Name.IndexOf(query), .Product = m} _ 
  Where m.Name.IndexOf(query) > 0
Heinzi
Did you read that post? It sounds to me like they strongly reject the idea.
Daniel Earwicker
@Daniel: Thanks, my memory tricked me. I fixed my answer.
Heinzi
+1  A: 

No there is no way of doing this (With can only be used with a constructor). It would violate the functional principles on which linq is built, specifically that there will not be side-effects.

Best bet is to create a new Product in your select with the Match property set.

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 _
              } 
Simon Fox
This does exactly what I need to achieve! Thanks a lot
Ropstah
A: 

With an extension method on System.Object that accepts a lambda, you can simulate such a feature fairly closely. There's an example in this answer, but it's in C#. It's probably not too hard to translate to VB.NET.

Daniel Earwicker
+1  A: 

In VB.Net there are two uses of the keyword With.

The first is object initialization. It's a means of assigning properties or fields of an object in the same line as an initialization expression without the need of a specific constructor for every permutation of fields.

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

This type of expression can only be used to create new objects. It cannot be used to modify existing ones.

The second use is the With statement. This allows you to put an object in context so to speak and call many . operations on it without qualification.

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

Neither of these though will allow you to use an existing object as a template for creating a new object.

JaredPar
+1 for last sentence :)
Ropstah