Question

Firstly I can't get my head around the functional / Lambda aspects of .NET 3.5. I use these features everyday in LINQ, but my problem is understanding the implementation, and what they really mean (Lambda? System.Func? etc etc)

With this in mind, how would the following be achieved:

As an example, I'd like to have an Extension method for List(Of T) which sets the properties of all the objects in the List to a certain value, and returns the updated List(Of T). It would be called like this:

VB:

 Dim someList As List(Of TextBox) =  (New List(Of TextBox)).UpdateExtension(Function(txtb) txtb.Text = "something")

C#:

List<TextBox> someList = (new List<TextBox>()).UpdateExtension(txtb => txtb.Text = "something");

What would the Extension method look like, in both VB and C#?

i.e:

 <Extension()> _
 Public Function UpdateExtension(Of T)(ByVal source As List(Of T), ByVal predicate As ??) As List(Of T)
        '??
 End Function

cheers!

EDIT

As many have pointed out, the above can be achieved, more or less, with .ForEach(). But my interest is in understading how something like .ForEach() is implemented, i.e. I'm interested in the implementation of the solution for the above problem.

Was it helpful?

Solution

Really you're miking and matching extension methods here. It's almost a combination of Select and ForEach. It appears you want a method that will allow you to both modify elements of a list and return the original enumeration. The following should do the trick for you.

VB.Net

<Extension()> _
Public Function UpdateExtension(Of T)(ByVal source As IEnumerable(Of T), ByVal del As Action(Of T)) As IEnumerable(Of T)
  For Each cur in source
    del(cur)
  Next
  Return source
End Function

C#

public static IEnumerable<T> UpdateExtension<T>(this IEnumerable<T> source, Action<T> del) {
  foreach ( var cur in source ) {
    del(cur);
  }
  return source;
}

OTHER TIPS

With the exception that you would modify the list in place rather than returning a new one, this is just a .ForEach() call.

To really understand how this works, think more in terms of IEnumerables than Lists. Think about why the two expressions below have the same result and why the latter is generally preferable:

MyEnumerable.Count() > 2
MyEnumerable.Skip(2).Any()

To help accomplish this, re-implement some standard IEnumerable extensions using C#'s yield keyword. Once you really get why the 2nd performs better you should be in good shape.

As for the different basic delegate types, you just need to learn them. Think of Func as your basic common delegate, where you specify the argument type and return type for the generic type parameters. Then think of Action as a special case of Func where the return type is void and Predicate as a special case where the return type is bool.

Extensions are implemented in a static class by static methods that take the target of the extension as the first parameter preceded by the this keyword. To implement your example I would do:

public static class ListBoxExtensions
{
  public static List<TextBox> SetToValue(this List<TextBox> txtBoxes, string sValue)
  {
    txtBoxes.ForEach(txtBox => txtBox.Text = sValue);
    return txtBoxes;
  }
}

and to use this on a Windows form with 3 textboxes:

private void Form1_Load(object sender, EventArgs e)
{
  List<TextBox> boxes = new List<TextBox>
                        {
                          textBox1,
                          textBox2,
                          textBox3
                        }.SetToValue("Hello");
}

Sorry - don't speak VB.

Hope this helps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top