linq如何建立一个where谓词
linq how to build a where predicate
我想查询一个 IEnumerable 形状。我有不同种类的形状,它们根据形状的类型以不同的方式与给定坐标相关。
对于任何给定的坐标,我想找到它的相关形状。我想用 Linq 来做到这一点。但是由于缺乏理解而陷入困境。搜索和阅读了几个小时,但我可以找到正确的词来让我举例说明我正在尝试做的事情。下面是一些代码,希望能展示我想做但显然行不通的概念。必须有一种方法可以链接这些表达式 - 我已经看到谓词构建器并且可能会使用它,但我想先学习更多基础知识。
我该怎么做?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
namespace LinqLearning
{
public class Coordinate
{
public double X { get; set; }
public double Y { get; set; }
}
public abstract class Bounded
{
public Coordinate TopRight { get; set; }
public Coordinate BottomLeft { get; set; }
}
public class Shape1 : Bounded
{ }
public class Shape2 : Bounded
{ }
public class LinqExperiments
{
public IEnumerable<Bounded> GetSquaresNearPoint(IEnumerable<Bounded> shapesEnumerable, Coordinate locator)
{
Expression<Func<Bounded, Coordinate, bool>> Shape1NearCoordinate =
(shape, coord) => shape.TopRight.Y > coord.Y &&
shape.BottomLeft.Y < coord.Y &&
shape.TopRight.X == coord.X;
Expression<Func<Bounded, Coordinate, bool>> Shape2NearCoordinate =
(shape, coord) => shape.TopRight.Y == coord.Y &&
shape.TopRight.X < coord.X + 3 &&
shape.TopRight.X > coord.X - 3;
Expression<Func<IQueryable<Bounded>, Coordinate, bool>> predicate = (shapes, coord) => Shape1NearCoordinate || Shape2NearCoordinate;
return shapesEnumerable.AsQueryable().Where(predicate);
}
}
}
我真的不明白你为什么使用 Expression
和 IQueryable
。我认为这可以通过 Func<Bounded, Coordinate, bool>
:
来解决
public IEnumerable<Bounded> GetSquaresNearPoint(IEnumerable<Bounded> shapesEnumerable, Coordinate locator)
{
Func<Bounded, Coordinate, bool> Shape1NearCoordinate =
(shape, coord) => shape.TopRight.Y > coord.Y &&
shape.BottomLeft.Y < coord.Y &&
shape.TopRight.X == coord.X;
Func<Bounded, Coordinate, bool> Shape2NearCoordinate =
(shape, coord) => shape.TopRight.Y == coord.Y &&
shape.TopRight.X < coord.X + 3 &&
shape.TopRight.X > coord.X - 3;
Func<Bounded, Coordinate, bool> predicate = (shapes, coord) => Shape1NearCoordinate(shapes, coord) || Shape2NearCoordinate(shapes, coord);
return shapesEnumerable.Where(x => predicate(x, locator));
}
为什么不坚持简单的函数呢?在不需要时不需要使用 Lambda
或 Linq Expressions
。
static bool Shape1NearCoordinate(Bounded shape, Coordinate coord) {
return shape.TopRight.Y > coord.Y &&
shape.BottomLeft.Y < coord.Y &&
shape.TopRight.X == coord.X;
}
static bool Shape2NearCoordinate(Bounded shape, Coordinate coord) {
return shape.TopRight.Y == coord.Y &&
shape.TopRight.X < coord.X + 3 &&
shape.TopRight.X > coord.X - 3;
}
public IEnumerable<Bounded> GetSquaresNearPoint(IEnumerable<Bounded> shapesEnumerable, Coordinate locator) {
return shapesEnumerable.Where(shape => Shape1NearCoordinate(shape, locator) || Shape2NearCoordinate(shape, locator));
}
我想查询一个 IEnumerable 形状。我有不同种类的形状,它们根据形状的类型以不同的方式与给定坐标相关。
对于任何给定的坐标,我想找到它的相关形状。我想用 Linq 来做到这一点。但是由于缺乏理解而陷入困境。搜索和阅读了几个小时,但我可以找到正确的词来让我举例说明我正在尝试做的事情。下面是一些代码,希望能展示我想做但显然行不通的概念。必须有一种方法可以链接这些表达式 - 我已经看到谓词构建器并且可能会使用它,但我想先学习更多基础知识。 我该怎么做?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
namespace LinqLearning
{
public class Coordinate
{
public double X { get; set; }
public double Y { get; set; }
}
public abstract class Bounded
{
public Coordinate TopRight { get; set; }
public Coordinate BottomLeft { get; set; }
}
public class Shape1 : Bounded
{ }
public class Shape2 : Bounded
{ }
public class LinqExperiments
{
public IEnumerable<Bounded> GetSquaresNearPoint(IEnumerable<Bounded> shapesEnumerable, Coordinate locator)
{
Expression<Func<Bounded, Coordinate, bool>> Shape1NearCoordinate =
(shape, coord) => shape.TopRight.Y > coord.Y &&
shape.BottomLeft.Y < coord.Y &&
shape.TopRight.X == coord.X;
Expression<Func<Bounded, Coordinate, bool>> Shape2NearCoordinate =
(shape, coord) => shape.TopRight.Y == coord.Y &&
shape.TopRight.X < coord.X + 3 &&
shape.TopRight.X > coord.X - 3;
Expression<Func<IQueryable<Bounded>, Coordinate, bool>> predicate = (shapes, coord) => Shape1NearCoordinate || Shape2NearCoordinate;
return shapesEnumerable.AsQueryable().Where(predicate);
}
}
}
我真的不明白你为什么使用 Expression
和 IQueryable
。我认为这可以通过 Func<Bounded, Coordinate, bool>
:
public IEnumerable<Bounded> GetSquaresNearPoint(IEnumerable<Bounded> shapesEnumerable, Coordinate locator)
{
Func<Bounded, Coordinate, bool> Shape1NearCoordinate =
(shape, coord) => shape.TopRight.Y > coord.Y &&
shape.BottomLeft.Y < coord.Y &&
shape.TopRight.X == coord.X;
Func<Bounded, Coordinate, bool> Shape2NearCoordinate =
(shape, coord) => shape.TopRight.Y == coord.Y &&
shape.TopRight.X < coord.X + 3 &&
shape.TopRight.X > coord.X - 3;
Func<Bounded, Coordinate, bool> predicate = (shapes, coord) => Shape1NearCoordinate(shapes, coord) || Shape2NearCoordinate(shapes, coord);
return shapesEnumerable.Where(x => predicate(x, locator));
}
为什么不坚持简单的函数呢?在不需要时不需要使用 Lambda
或 Linq Expressions
。
static bool Shape1NearCoordinate(Bounded shape, Coordinate coord) {
return shape.TopRight.Y > coord.Y &&
shape.BottomLeft.Y < coord.Y &&
shape.TopRight.X == coord.X;
}
static bool Shape2NearCoordinate(Bounded shape, Coordinate coord) {
return shape.TopRight.Y == coord.Y &&
shape.TopRight.X < coord.X + 3 &&
shape.TopRight.X > coord.X - 3;
}
public IEnumerable<Bounded> GetSquaresNearPoint(IEnumerable<Bounded> shapesEnumerable, Coordinate locator) {
return shapesEnumerable.Where(shape => Shape1NearCoordinate(shape, locator) || Shape2NearCoordinate(shape, locator));
}