19

I've been busy diving into lambda expressions recently, and there's some specific functionality that I've been meaning to learn but just couldn't seem to make heads or tails of.

Suppose that I have the following logic in my code:

List<A> foo; // assuming this is populated
string[] bar = foo.Select<A,string>(x => x.StringProperty).ToArray<string>();

Now, I want to perhaps abstract that whole operation into a handler method so that I can do this instead:

string[] bar = MakeArray<A,string>(foo, x => x.StringProperty);
int[] foobar = MakeArray<A,int>(foo, x => x.IntegerProperty);

How would I go about with writing that method's body? I foresee declaring the signature as something like:

U[] MakeArray<T,U>( /* some lambda magic? */ ) where T : IEntity {}

but I don't know how to specify that I'm expecting a lambda expression as the method argument, and how that translates exactly into the body of the method.

Can anybody show me how to create the MakeArray() function above? I'm pretty sure that once I see how it's done, that I can pick it up from there.

EDIT

As pointed out in the comments, MakeArray() needed a reference to the IEnumerable<>. Updated to reflect that.

4
  • 5
    FWIW the implicit nature of the generics can add a readable value to your code by not having to explicitly state the type with each statement, this could be subjective though. The following statement is equal to your first select.. string[] bar = foo.Select(x => x.StringProperty).ToArray(); Commented Mar 22, 2011 at 19:36
  • If you find yourself using arrays all over your code, you may want to consider refactoring them into IEnumerable<T> or IList<T>. Then none of this will be necessary. Also, doesn't MakeArray need a reference to foo? Commented Mar 22, 2011 at 19:44
  • @Quintin ~ Yeah, I kind of just like the generics explicitly stated (when applicable) just so it's clear what I'm pulling out. You're correct though. Commented Mar 22, 2011 at 19:45
  • @BlueRaja ~ nah, the array thing is just to illustrate. But, I see your point though! Commented Mar 22, 2011 at 19:47

5 Answers 5

16
public static U[] MakeArray<T, U>(this IEnumerable<T> @enum, Func<T, U> rule)
{
    return @enum.Select(rule).ToArray();
}
Sign up to request clarification or add additional context in comments.

1 Comment

+1 thanks! I'm going with this answer for showing how exactly the Func<> parameter that comes into the method is used. real helpful.
13

Try the following

U[] MakeArray<T,U>(Func<T, U> projection) where T : IEntity {
  ...
}

When passing lambdas as arguments you generally want the matching parameter to be a delegate. In most cases you should just use the appropriate Action<> or Func<> value. The former for void returning lambdas and the latter for ones that return values.

Comments

2

You're looking for Action<> and Func<>.

Comments

2

You can use the Func and Action classes. Check out the LINQ Where function's signature for an example: http://msdn.microsoft.com/en-us/library/bb534803.aspx

1 Comment

Thanks for the link! I always wondered how they implemented all that magic.
1

You can create extension

public static class MakeArrayExtension
{
    public static U[] MakeArray<T, U>(this IEnumerable<T> collection, Func<T,U> func)
    {
        return collection.Select(func).ToArray();
    }
}

And then use it like this

List<A> foo; // assuming this is populated
string[] bar = foo.MakeArray<A,string>(x => x.StringProperty);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.