在以下代码的ContainsIngredients方法中,是否可以缓存p.Ingredients值而不是多次显式引用它?这是我刚熟了用于说明目的相当简单的例子,但我工作的引用代码值深处p如.p.InnerObject.ExpensiveMethod().值
编辑:我正在使用来自http://www.albahari.com/nutshell/predicatebuilder.html的PredicateBuilder
public class IngredientBag { private readonly Dictionary_ingredients = new Dictionary (); 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 > ContainsIngredients(string ingredientType, params string[] ingredients) { var predicate = PredicateBuilder.False (); // 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 { 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); } }
Steve Cooper.. 10
你考虑过Memoization吗?
基本的想法是这样的; 如果你有一个昂贵的函数调用,有一个函数将在第一次调用时计算昂贵的值,但之后返回一个缓存的版本.功能看起来像这样;
static FuncRemember (Func 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 FuncMyExpensiveMethod = () => { System.Threading.Thread.Sleep(5000); return "that took ages!"; }; // and heres a function call that only calculates it the once. Func 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());
作为一般战略,它可能会有所帮助.
你考虑过Memoization吗?
基本的想法是这样的; 如果你有一个昂贵的函数调用,有一个函数将在第一次调用时计算昂贵的值,但之后返回一个缓存的版本.功能看起来像这样;
static FuncRemember (Func 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 FuncMyExpensiveMethod = () => { System.Threading.Thread.Sleep(5000); return "that took ages!"; }; // and heres a function call that only calculates it the once. Func 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());
作为一般战略,它可能会有所帮助.