33

I recently had the opportunity to tweak some Java code and was able to take advantage of some new Java 8 features. In one particular case I needed to get a List of (String) .Name properties from a List of objects. A simplified example of what I did was:

// sample data: <Thing> objects have a single String property called "Name" 
List<Thing> thingList =
    new ArrayList<>(Arrays.asList(new Thing("Thing1"), new Thing("Thing2")));

// first pass
List<String> nameList = new ArrayList<>();
thingList.forEach(x -> nameList.add(x.getName()));

// refinement 1: use stream, map, and collect
List<String> nameList1 =
    thingList.stream().map(x -> x.getName()).collect(Collectors.toList());

// refinement 2: use "Thing::getName" method reference
List<String> nameList2 =
    thingList.stream().map(Thing::getName).collect(Collectors.toList());

I was curious to see how those approaches would translate to C#, and I got

// sample data: <Thing> objects have a single String property called "Name"
var thingList = new List<Thing> { new Thing("Thing1"), new Thing("Thing2") };

// first pass
var nameList = new List<String>();
thingList.ForEach(x => nameList.Add(x.Name));

// refinement 1: use Select and ToList
List<String> nameList1 = thingList.Select(x => x.Name).ToList();

What I haven't found (yet?) is a C# equivalent of "refinement 2" to replace the Lambda expression with something (a little bit) more concise. Is there a C# equivalent to the Java 8 "method reference" in this case, given that I'm trying to get a property of each object (which in Java is done using a getProperty method)?

Ryan Lundy
  • 196,074
  • 36
  • 176
  • 207
Gord Thompson
  • 107,466
  • 28
  • 191
  • 387

2 Answers2

12

You would have to declare a method outside of Thing (or a static Thing method), then you could pass a method-group reference to it:

private string GetName(Thing thing)
{
    return thing.Name;
}

...

List<String> nameList1 = thingList.Select(GetName).ToList();

In C# 6, you can also use an expression-bodied function to save a couple of lines:

private string GetName(Thing thing) => thing.Name;
Blorgbeard
  • 97,316
  • 47
  • 222
  • 267
  • But `.Select(GetName)` is a syntax sugar that looks like a method reference, essentially it's still `.Select(x => GetName(x))`. – Cheng Chen May 12 '16 at 03:30
  • 1
    Pretty sure it's a method reference. But so what if it's sugar? OP just wants shorter code. What's the difference? – Blorgbeard May 12 '16 at 03:39
  • 8
    @Danny Chen: “essentially” Java 8’s method reference also is syntactic sugar for a lambda expression invoking the specified method. Though, technically, it’s the other way round, a lambda expression is syntactic sugar for a method reference to an additional method holding the lambda’s body. – Holger May 12 '16 at 08:42
7

c# has a equivalent, this feature is callind Method Group

see more:

What is a method group in C#?

sample:

private static int[] ParseInt(string s)
{
    var t = ParseString(s);
    var i = t.Select(x => int.Parse(x));
    return i.ToArray();
}

with metod group:

private static int[] ParseInt(string s)
{
    var t = ParseString(s);
    var i = t.Select(int.Parse);
    return i.ToArray();
}
Adriano Moreira
  • 115
  • 1
  • 3