LINQ 选择表达式中的解构

kim*_*gro 6 c#

Deconstruct给定一个具有如下方法的对象:

record Point(int X, int Y);

var point = new Point(1, 2);
var (x, y) = point;

Console.WriteLine(x); // 1
Console.WriteLine(y); // 2
Run Code Online (Sandbox Code Playgroud)

是否可以在 LINQ select 语句中解构对象的值?

例如而不是:

points.Select(p => p.X + p.Y)
Run Code Online (Sandbox Code Playgroud)

// CS0019 Operator '+' cannot be applied to operands of type 'UserQuery.Point' and 'int'
points.Select((x, y) => x + y)
Run Code Online (Sandbox Code Playgroud)

这会导致编译错误,因为它使用的Select方法重载需要Func<Point, int>

may*_*ʎɐɯ 7

这是我在没有扩展方法的情况下如何做到的,只要我的点对象可以按照您的问题所示进行解构,我就可以执行以下操作:

points.Select(p =>
{
    // deconstruct each element of the object
    var (x, y) = p;
    return x + y;
});
Run Code Online (Sandbox Code Playgroud)

排成一行

points.Select(p => { var (x, y) = p; return x + y; });
Run Code Online (Sandbox Code Playgroud)

我希望它能解决你的问题


D-S*_*hih 3

在默认库中,Select扩展方法允许被IEnumerable集合对象使用。

方法签名如下所示。

public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector);
Run Code Online (Sandbox Code Playgroud)

如果您想解构为选择表达式,您可以尝试编写自定义Select扩展方法。

public static class PointExt
{
    public static IEnumerable<T> Select<T>(this IEnumerable<Point> points, Func<int, int, T> selector)
    {
        foreach (var p in points)
        {
            yield return selector(p.X, p.Y);
        }
    }

    public static T Select<T>(this Point p, Func<int, int, T> selector)
    {
        return selector(p.X, p.Y);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后就可以用这个代码片段了。

public static void Main()
{
    var point = new Point(1, 2);
    List<Point> points = new List<Point>(){ point };
    var res = points.Select((x, y) => x + y);
    Console.WriteLine(res.First());
    Console.WriteLine(point.Select((x, y) => x + y));
}
Run Code Online (Sandbox Code Playgroud)

时间:2019-03-17 标签:c#online