C#中与Java 8中的“方法引用”相当的是什么?

38

最近我有机会调整一些Java代码,并且能够利用一些新的Java 8特性。在一个特定的情况中,我需要从对象列表中获取一个 (String) .Name 属性的列表。下面是我所做的简化示例:

// 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());

我很好奇这些方法如何转换成C#,结果我得到了

// 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();

我还没有找到C#中等效于“refinement 2”的方法,可以用更简洁的东西替换Lambda表达式。在这种情况下,是否存在C#等效于Java 8的“方法引用”,特别是当我尝试获取每个对象的一个属性时(Java中使用getProperty 方法)?

2个回答

12

你需要在Thing之外声明一个方法(或者静态的Thing方法),然后你可以将一个方法组引用传递给它:

你需要在Thing之外声明一个方法(或者静态的Thing方法),然后你可以将一个方法组引用传递给它:

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

...

List<String> nameList1 = thingList.Select(GetName).ToList();
在C# 6中,你也可以使用表达式主体函数来节省几行代码:
private string GetName(Thing thing) => thing.Name;

但是.Select(GetName)只是一种看起来像方法引用的语法糖,本质上它仍然是.Select(x => GetName(x)) - Cheng Chen
1
很确定这是一个方法引用。但如果这只是语法糖又怎样呢?楼主只是想要更短的代码。有什么区别呢? - Blorgbeard
8
Java 8的方法引用“本质上”也是语法糖,可以调用指定方法的lambda表达式。虽然实际上情况相反,lambda表达式是一个语法糖,用于引用一个额外的方法来保存lambda表达式的主体。请注意,这里不需要解释其他内容。 - Holger

7

C#有一个类似的特性叫做方法组。

查看更多:
C#中的方法组是什么?

示例:

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

使用方法组:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接