【发布时间】:2018-06-07 03:49:41
【问题描述】:
假设我的 C# 代码定义如下,我想向控制台返回一个输出,显示列表或汽车中最常见的燃料类型。
// set delegates defining rules as a function that takes list of cars and returns an int
Func<List<Car>, int> CountElectric = (cars) => cars
.GroupBy(c => c.IsElectric == true).Count(); // count electric cars
Func<List<Car>, int> CountGassoline = (cars) => cars
.GroupBy(c => c.FuelType == FuelTypes.Gassoline).Count(); // count cars using gassoline
Func<List<Car>, int> CountDiesel = (cars) => cars
.GroupBy(c => c.FuelType == FuelTypes.Diesel).Count(); // Count cars using diesel
// Add rules to dictionary of (Key=CarType, Value=Func<List<Car>, bool>
CarsRules = new Dictionary<CarType, Func<List<Car>, int>>()
{
{FueldType.Electric, CountElectric},
{FueldType.Diesel,CountDiesel},
{FueldType.Gassoline, CountGassoline}
};
// Create List of Cars and add some cars
List<Car> cars = new List<Car>();
cars.Add(new Car()
{Id = Guid, Name = "Tesla", IsElectric = true, FuelType = FuelTypes.Electric};
cars.Add(new Car()
{Id = Guid, Name = "VW", IsElectric = false, FuelType = FuelTypes.Gassoline};
cars.Add(new Car()
{Id = Guid, Name = "Toyota", IsElectric = false, FuelType = FuelTypes.Gassoline};
cars.Add(new Car()
{Id = Guid, Name = "Volvo", IsElectric = false, FuelType = FuelTypes.Diesel};
在上面的汽车列表中,汽油是最常见的。我怎么知道呢? IE 我想在控制台上只显示“汽油”
如果我在上面的列表中打成平手,例如 2 辆使用汽油的汽车和 2 辆使用柴油的汽车,我将如何找到并退回两者? IE 我想在控制台上同时显示“汽油”和“柴油”
我很难理解这种结构,我想像下面这样用老式的方式来做,但我很清楚应该有更优雅的方式来使用 Func 代表
public List<string> GetMostUsedFuelTypes(List<Car> cars)
{
List<string> winners = new List<string>();
int CountElectric = 0;
int CountGassoline = 0;
int CountDiesel = 0;
foreach(var car in cars)
{
// Count and return fuel type that occurs most, if a tye, return the highest counts
}
return winners;
}
【问题讨论】:
-
与问题无关的改进建议:
Func<List<Car>, bool> CountElectric = (cars) => cars.GroupBy(c => c.IsElectric == true).Count();可能比Func<List<Car>, bool> CountElectric = (cars) => cars.Count(c => c.IsElectric == true);更好如果IsElectric的类型是bool(而不是bool?),那么您也可以删除==true. -
Func<List<Car>, int> CountElectric = (cars) => cars.GroupBy(c => c.IsElectric == true).Count()不计算有多少电动汽车。它计算c.IsElectric == true有多少个结果——最多两个。你想要的是Func<List<Car>, int> CountElectric = (cars) => cars.Where(c => c.IsElectric == true).Count()。 -
@Enigmativity ...然后可以进一步改进,因为执行“Where”后跟“Count”是浪费:它创建一个对象列表然后计算它们。您可以使用 lambda 表达式将“Where”更改为“Count”,该表达式只保留计数。尽管您的解释比我的要清楚得多,但这使您获得了我之前评论中的价值。 :)
-
@Richardissimo - 执行
Where/Count与带有 lambda 的Count的运行时性能几乎没有区别。 -
@Enigmativity 是的,你是对的,因为我说它创建一个列表是错误的,它只是在处理一个可枚举的。
(cars) => cars.Count(car => car.IsElectric)仍然更容易阅读。
标签: c# dictionary lambda delegates func