LINQ select中的匿名函数

r1zhe5dt  于 2023-07-31  发布在  其他
关注(0)|答案(1)|浏览(93)

我有一个这样的代码:

List<Item> items;
if (maxPrice)
{
    items = itemsQuery
        .Select(x => new Item()
        {
            Title = x.Key.title,
            Description = x.Key.desc,
            Stock = x.Key.stock,
            Price = x.Max(y => y.price)
        }).ToList();
}
else if (minPrice)
{
    items = itemsQuery
        .Select(x => new Item()
        {
            Title = x.Key.title,
            Description = x.Key.desc,
            Stock = x.Key.stock,
            Price = x.Min(y => y.price)
        }).ToList();
}
else
{
    items = itemsQuery
        .Select(x => new Item()
        {
            Title = x.Key.title,
            Description = x.Key.desc,
            Stock = x.Key.stock,
            Price = x.Average(y => y.price)
        }).ToList();
}

字符串
是否可以只更改Price = x.DynamicFunc(...)行?因为除此之外都是一样的。
我试过:

Price = (x) => {
  if (maxPrice) { return x.Max(y => y.price)}
  else if (minPrice) { return x.Min(y => y.price)}
  else { return x.Average(y => y.price)}
}


但这给了我一个错误:

Cannot convert lambda expression to type "decimal" because it is not a delegate type.


我怎样才能简化这个过程,使我不必在3个if分支中重复整个选择过程?

fwzugrvs

fwzugrvs1#

模拟代码

如果我没理解错的话。您的代码可能看起来像这样:

public class ItemCollectionKey
{
    public string title = "";
    public string desc = "";
    public int stock;
}
public class ItemCollection : IEnumerable<Item>
{
    public ItemCollectionKey Key = new ItemCollectionKey();
    private List<Item> items = new List<Item>();

    public IEnumerator<Item> GetEnumerator()
    {
        return items.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}
public class Item
{
    public string Title { get; set; } = "";
    public string Description { get; set; } = "";
    public int Stock { get; set; }
    public decimal price;
    public decimal Price { get => price; set => price = value; }
}
public class ItemsQuery : IEnumerable<ItemCollection>
{
    List<ItemCollection> data = new List<ItemCollection>();
    public IEnumerator<ItemCollection> GetEnumerator()
    {
        return data.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

字符串
它可以与您的源代码不同,但我认为这不会影响解决方案。

我的解决方案

有了上面的代码,我们就可以用下面的代码实现你的目标:

//mock data
var itemCollection_01 = new ItemCollection();
itemCollection_01.Key = new ItemCollectionKey() { title = "key1", desc = "key1_desc", stock = 100 };
itemCollection_01.Add(new Item() { Title = "item1", Description = "item1_desc", Stock = 43, Price = 12.1m });
itemCollection_01.Add(new Item() { Title = "item2", Description = "item2_desc", Stock = 57, Price = 34.2m });
var itemCollection_02 = new ItemCollection();
itemCollection_02.Key = new ItemCollectionKey() { title = "key2", desc = "key2_desc", stock = 200 };
itemCollection_02.Add(new Item() { Title = "item3", Description = "item3_desc", Stock = 93, Price = 56.3m });
itemCollection_02.Add(new Item() { Title = "item4", Description = "item4_desc", Stock = 107, Price = 78.4m });
ItemsQuery itemsQuery = new ItemsQuery();
itemsQuery.Add(itemCollection_01);
itemsQuery.Add(itemCollection_02);

//condition
bool maxPrice = false;
bool minPrice = false;

List<Item> items;

//assign function accordingly
Func<ItemCollection, decimal> getPrice;
if (maxPrice)
{
    getPrice = (ItemCollection ic) => { return ic.Max(y => y.price); };
}
else if (minPrice)
{
    getPrice = (ItemCollection ic) => { return ic.Min(y => y.price); };
}
else
{
    getPrice = (ItemCollection ic) => { return ic.Average(y => y.price); };
}

//run query
items = itemsQuery.Select(x => new Item()
{
    Title = x.Key.title,
    Description = x.Key.desc,
    Stock = x.Key.stock,
    Price = getPrice(x)
}).ToList();

//print output
System.Console.WriteLine(String.Join(", ", (from item in items select item.Price)));

解释

我们声明了Func<ItemCollection, decimal> getPrice;,但为每个条件分配了不同的函数。然后我们运行:

items = itemsQuery.Select(x => new Item()
{
    Title = x.Key.title,
    Description = x.Key.desc,
    Stock = x.Key.stock,
    Price = getPrice(x)
}).ToList();


getPrice(x)应执行相应的函数。

可能的输出

when maxPrice is true:
34.2, 78.4

when minPrice is true:
12.1, 56.3

when maxPrice and minPrice are false:
23.15, 67.35

相关问题