views:

44

answers:

1
+2  Q: 

Lambda and VB.NET

Hello,

I have found this example on StackOverflow:

var people = new List<Person> {
    new Person{Name="aaa", Salary=15000, isHip=false}
    ,new Person{Name="aaa", Salary=15000, isHip=false}
    ,new Person{Name="bbb", Salary=20000, isHip=false}
    ,new Person{Name="ccc", Salary=25000, isHip=false}
    ,new Person{Name="ddd", Salary=30000, isHip=false}
    ,new Person{Name="eee", Salary=35000, isHip=false}
};


people.Where(p => p.Salary < 25000).Update(p => p.isHip = true);

foreach (var p in people)
{
Console.WriteLine("{0} - {1}", p.Name, p.isHip);
}

public static void Update<T>(this IEnumerable<T> source, Action<T> action)
{
foreach (var item in source)
    action(item);
}

In C# everything works fine. I tried to convert it in VB.NET. Here's the code:

<System.Runtime.CompilerServices.Extension()> _
Public Sub Update(Of T)(ByVal source As IEnumerable(Of T), ByVal action As Action(Of T))
    For Each item In source
        action(item)
    Next item
End Sub

If I try to update my collection things don't work, though:

people.Where(Function(p) p.Salary < 25000).Update(Function(p) p.isHip = true)

I am using VS2008 (3.5) This thing is driving me crazy.

Is there anybody who can help me?

Alberto

+1  A: 

You should always post what exactly is not working.


In your case, you want to Update list elements, which works though passing an Action(Of T) that should be run for every element.

Such an action, that is just run, performs some side-effects but returns no value is described by exactly one VB construct: A Sub.

Thus what you would want to write is

.Update(Sub(p) p.isHip = true)

which is valid VB2010, but simply does not work in the 2008 version. C# doesn't have a problem there, but in your VB code, you want to pass a Function which has to produce a value and not just perform an assignment. Func(Of ...) would be the appropriate type of that expression.

So what to do? You can't just express what you want in the syntax of your version. But probably you shouldn't - build a new collection without modifying an old one. Is soon as you're dealing with value types/properties, the above approch won't work at all, since actually a temporary collection returned by Where is modified. Linq is no modification language, but a query system.

Anyway: Just use a plain loop.

Dario
Thanks for your help, Dario. I explained what was my problem: "If I try to update my collection things don't work". Anyway, I've found out I can do something like this: .Update(AddressOf UpdateIsHip) where UpdateIsHip is my Function (or Sub) which does exactely what I expected.
vandalo