gpt4 book ai didi

c# - 是否可以缓存在 lambda 表达式中计算的值?

转载 作者:太空狗 更新时间:2023-10-30 00:09:36 24 4
gpt4 key购买 nike

在以下代码的 ContainsIngredients 方法中,是否可以缓存 p.Ingredients 值而不是显式多次引用它?这是一个相当简单的示例,我只是为了说明目的而编造的,但我正在处理的代码引用了 p 内部的值,例如。 p.InnerObject.ExpensiveMethod().Value

编辑:我正在使用来自 http://www.albahari.com/nutshell/predicatebuilder.html 的 PredicateBuilder

public class IngredientBag
{
private readonly Dictionary<string, string> _ingredients = new Dictionary<string, string>();

public void Add(string type, string name)
{
_ingredients.Add(type, name);
}

public string Get(string type)
{
return _ingredients[type];
}

public bool Contains(string type)
{
return _ingredients.ContainsKey(type);
}
}

public class Potion
{
public IngredientBag Ingredients { get; private set;}
public string Name {get; private set;}

public Potion(string name) : this(name, null)
{

}

public Potion(string name, IngredientBag ingredients)
{
Name = name;
Ingredients = ingredients;
}

public static Expression<Func<Potion, bool>>
ContainsIngredients(string ingredientType, params string[] ingredients)
{
var predicate = PredicateBuilder.False<Potion>();
// Here, I'm accessing p.Ingredients several times in one
// expression. Is there any way to cache this value and
// reference the cached value in the expression?
foreach (var ingredient in ingredients)
{
var temp = ingredient;
predicate = predicate.Or (
p => p.Ingredients != null &&
p.Ingredients.Contains(ingredientType) &&
p.Ingredients.Get(ingredientType).Contains(temp));
}

return predicate;
}

}


[STAThread]
static void Main()
{
var potions = new List<Potion>
{
new Potion("Invisibility", new IngredientBag()),
new Potion("Bonus"),
new Potion("Speed", new IngredientBag()),
new Potion("Strength", new IngredientBag()),
new Potion("Dummy Potion")
};

potions[0].Ingredients.Add("solid", "Eye of Newt");
potions[0].Ingredients.Add("liquid", "Gall of Peacock");
potions[0].Ingredients.Add("gas", "Breath of Spider");

potions[2].Ingredients.Add("solid", "Hair of Toad");
potions[2].Ingredients.Add("gas", "Peacock's anguish");

potions[3].Ingredients.Add("liquid", "Peacock Sweat");
potions[3].Ingredients.Add("gas", "Newt's aura");

var predicate = Potion.ContainsIngredients("solid", "Newt", "Toad")
.Or(Potion.ContainsIngredients("gas", "Spider", "Scorpion"));

foreach (var result in
from p in potions
where(predicate).Compile()(p)
select p)
{
Console.WriteLine(result.Name);
}
}

最佳答案

你有没有考虑过Memoization

基本思路是这样的;如果你有一个昂贵的函数调用,有一个函数会在第一次调用时计算昂贵的值,但之后返回一个缓存的版本。函数看起来像这样;

static Func<T> Remember<T>(Func<T> GetExpensiveValue)
{
bool isCached= false;
T cachedResult = default(T);

return () =>
{
if (!isCached)
{
cachedResult = GetExpensiveValue();
isCached = true;
}
return cachedResult;

};
}

这意味着你可以这样写;

    // here's something that takes ages to calculate
Func<string> MyExpensiveMethod = () =>
{
System.Threading.Thread.Sleep(5000);
return "that took ages!";
};

// and heres a function call that only calculates it the once.
Func<string> CachedMethod = Remember(() => MyExpensiveMethod());

// only the first line takes five seconds;
// the second and third calls are instant.
Console.WriteLine(CachedMethod());
Console.WriteLine(CachedMethod());
Console.WriteLine(CachedMethod());

作为一般策略,它可能会有所帮助。

关于c# - 是否可以缓存在 lambda 表达式中计算的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66382/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com