优化LINQ查询调用Where Newbie C#/LINQ问题



在下面这个简单而做作的例子中,我在Where子句中使用了一个方法(GetAutomaticCars(。这导致GetAutomaticCars被调用四次。我知道一种解决办法。只需先调用GetAutomaticCars,然后在查询中使用结果。我已经展示了下面的评论行。我的问题是:这是处理这个问题的唯一方法吗?编译器无法优化调用并意识到只需要调用GetAutomaticCars一次,这对我来说似乎有点奇怪。我想答案可能是:"_cars集合可能会更改(在另一个线程上("。如果是这样的话,有没有办法在C#中表明情况并非如此?或者我必须按照我的建议先调用GetAutomaticCars吗?

class Program
{
static void Main(string[] args)
{
CarTest test = new CarTest();
test.PerformTest();
}
}

public class CarTest
{
List<Car> _cars = new List<Car>() { new Car(1, "Mustang", false), new Car(2, "Corvette", false), new Car(3, "Subaru", true), new Car(4, "Volvo", true) };
public void PerformTest()
{
// this will just call GetAutomaticCars once
//var automaticCars = GetAutomaticCars();
//var optimalCars = _cars.Where(i => automaticCars.Select(p => p.Id).Contains(i.Id)).ToList();
// this will call GetAutomaticCars 4 times
var optimalCars = _cars.Where(i => !GetAutomaticCars().Select(p => p.Id).Contains(i.Id)).ToList(); 
Console.WriteLine("Optimal Cars");
foreach (var car in optimalCars)
{
Console.WriteLine(car);
}
}
private IEnumerable<Car> GetAutomaticCars()
{
return _cars.Where(p => p.Automatic == true);
}
}
public class Car
{
public Car(int id, string name, bool automatic)
{
Id = id;
Name = name;
Automatic = automatic;
}
public int Id { get; set; }
public string Name { get; set; }
public bool Automatic { get; set; }
}

这里有很多我们可以讨论的内容。例如:

  • 编译器无法安全地优化对方法的调用的各种原因
  • 你可以利用IQueryables想出一种不必要的复杂方法来优化你所说的通话

但我认为最重要的一点是,您已经获得了想要抽象到另一个方法中的逻辑(p => p.Automatic == true(,并且您希望有一种比迄今为止提出的更简单、更高效的方法将此逻辑应用于LINQ查询。以下是我的建议:

var optimalCars = _cars.Except(GetAutomaticCars()); 

你也可以从过滤现有汽车的概念中抽象出判断汽车是否自动的逻辑,然后更直接地使用这个逻辑:

private IsCarAutomatic(Car c) => c.IsAutomatic;
private IsCarOptimal(Car c) => !IsCarAutomatic(c);
...
var optimalCars = _cars.Where(IsCarOptimal);

最新更新