0

This is related to my question at Fun (?) with Linq Expressions in extension methods but this is more of an abstraction of a piece I'm trying to understand. I'm really having difficulty wrapping my brain around this concept.

Given an object defined as such:

public class item
{
    public int itemId { get; set; }
    public string itemName { get; set; }
    public string itemDescription { get; set; }
}

and an IEnumerable<item> foo,

let's say I want to write an extension method such that the expression

foo.GetFullDescription(x => x.itemId.ToString() + "(" + x.itemName + ")")

would equal an IEnumerable<string> containing the concatenated items as defined in the Lambda expression. For example, if my foo object contained exactly one item object like so:

{
fooItem.itemId = 1
fooItem.itemName = "foo"
fooItem.itemDescription = "fooDescription"
}

... and I assigned a variable to the result of the extension method like so:

var bar = foo.GetFullDescription(x => x.itemId.ToString() + "(" + x.itemName + ")");

... I would get bar to be an IEnumerable<string> with one item in it, and that item would equal 1(foo).

How would I write that extension method? The first part is relatively straightforward:

public static IEnumerable<string> GetFullDescription(this IEnumerable<item> target, <some expression?> expr){


}

Some help would be appreciated. Simple explanations would be very appreciated.

Community
  • 1
  • 1
Jeremy Holovacs
  • 22,480
  • 33
  • 117
  • 254

2 Answers2

1

Here's a working example from LINQPad. Just copy and past it in.

void Main()
{
    System.Console.WriteLine(GetFullDescription(new Item(){itemId = 2, itemName="two"}, 
    x => x.itemId.ToString() + "(" + x.itemName + ")"));
}

public delegate string Lambda (Item item);

public class Item
{
    public int itemId { get; set; }
    public string itemName { get; set; }
    public string itemDescription { get; set; }
}

// Define other methods and classes here
public static string GetFullDescription(Item item, Lambda lambda){
    return lambda(item);
}

You just have to declare a Delegate that returns a string, is called whatever you like, and accepts a single Item parameter. Remember a Delegate is basically a function variable, were you define your function's input and output. Here I think is your full extension method

public delegate string Lambda (Item item);
public static string GetFullDescription(this IEnumerable<Item> items, Lambda lambda){
    foreach(var item in items){
         return yield lambda(item); 
    }
}
Daryl
  • 18,592
  • 9
  • 78
  • 145
  • Hmm... this looks to be in the right direction of what I'm looking for, but rather tied to the `Item` class. I'll see if I can get this working with generics. – Jeremy Holovacs Oct 29 '11 at 11:47
  • I was able to use this in a generic manner. Fantastic, and a lot simpler than I thought it would be. Thanks a bunch! – Jeremy Holovacs Oct 29 '11 at 12:24
0

Based on your description (if I'm reading it correctly), it looks like you just need to use Select.

var itemsAsStrings = foo.Select(x => x.itemId.ToString() + "(" + x.itemName + ")");
Austin Salonen
  • 49,173
  • 15
  • 109
  • 139
  • There are lots of ways to accomplish this task, what I'm really looking for is an education on how to do it using a Linq Expression so that I could apply the idea more generically. – Jeremy Holovacs Oct 29 '11 at 11:43