【发布时间】:2019-11-02 01:17:49
【问题描述】:
在以下简单、人为的示例中,我在 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; }
}
【问题讨论】:
-
Where查询实际上是一个循环。如果您有一个循环,则不会在循环内调用该方法,而是在进入循环之前调用它一次。所以是的,你应该在这里做同样的事情。 -
您在 _cars 上的 Where on cars 中执行 Where...您确定要执行此操作而不是仅在 Where 上执行一次吗?你需要 ToList 吗?
-
在这种情况下,您可以在 _cars 和 GetAutomaticCars 之间使用
Join,GetAutomaticCars将被调用一次。像 ---_cars.Join(GetAutomaticCars()............) -
谢谢-user1672994,我会玩的。 Olivier,我从专有代码中简化了。有一个 ToList 所以我离开了它。在更长的实际代码中,Wheres 更有意义。
-
这就够了:
var optimalCars = _cars.Where(car => car.Automatic != true);
标签: c# linq optimization