<p>In the ContainsIngredients method in the following code, is it possible to cache the <em>p.Ingredients</em> value instead of explicitly referencing it several times?  This is a fairly trivial example that I just cooked up for illustrative purposes, but the code I'm working on references values deep inside <em>p</em> eg. <em>p.InnerObject.ExpensiveMethod().Value</em></p>

<p>edit:
I'm using the PredicateBuilder from <a href="http://www.albahari.com/nutshell/predicatebuilder.html" rel="nofollow noreferrer">http://www.albahari.com/nutshell/predicatebuilder.html</a></p>

<pre><code>public class IngredientBag
{
    private readonly Dictionary&lt;string, string&gt; _ingredients = new Dictionary&lt;string, string&gt;();

    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&lt;Func&lt;Potion, bool&gt;&gt; 
        ContainsIngredients(string ingredientType, params string[] ingredients)
    {
        var predicate = PredicateBuilder.False&lt;Potion&gt;();
        // 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 =&gt; p.Ingredients != null &amp;&amp;
                p.Ingredients.Contains(ingredientType) &amp;&amp;
                p.Ingredients.Get(ingredientType).Contains(temp));
        }

        return predicate;
    }

}


[STAThread]
static void Main()
{
    var potions = new List&lt;Potion&gt;
    {
        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);
    }
}
</code></pre>

[{'answer_id': 66710, 'author': 'Fake Jim', 'author_id': 6199, 'author_profile': 'https://Stackoverflow.com/users/6199', 'pm_score': 3, 'selected': True, 'text': "<p>Can't you simply write your boolean expression in a separate static function which you call from your lambda - passing p.Ingredients as a parameter...</p>\n\n<pre><code>private static bool IsIngredientPresent(IngredientBag i, string ingredientType, string ingredient)\n{\n    return i != null &amp;&amp; i.Contains(ingredientType) &amp;&amp; i.Get(ingredientType).Contains(ingredient);\n}\n\npublic static Expression&lt;Func&lt;Potion, bool&gt;&gt;\n                ContainsIngredients(string ingredientType, params string[] ingredients)\n{\n    var predicate = PredicateBuilder.False&lt;Potion&gt;();\n    // Here, I'm accessing p.Ingredients several times in one \n    // expression.  Is there any way to cache this value and\n    // reference the cached value in the expression?\n    foreach (var ingredient in ingredients)\n    {\n        var temp = ingredient;\n        predicate = predicate.Or(\n            p =&gt; IsIngredientPresent(p.Ingredients, ingredientType, temp));\n    }\n\n    return predicate;\n}\n</code></pre>\n"}, {'answer_id': 66749, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 0, 'selected': False, 'text': '<p>I would say no in this case. I assume that the compiler can figure out that it uses the <code>p.Ingredients</code> variable 3 times and will keep the variable closeby on the stack or the registers or whatever it uses.</p>\n'}, {'answer_id': 67309, 'author': 'Amy B', 'author_id': 8155, 'author_profile': 'https://Stackoverflow.com/users/8155', 'pm_score': 0, 'selected': False, 'text': '<p>Turbulent Intellect has the exactly right answer.</p>\n\n<p>I just want to advise that you can strip some of the nulls and exceptions out of the types you are using to make it friendlier to use them.</p>\n\n<pre><code>    public class IngredientBag\n    {\n      private Dictionary&lt;string, string&gt; _ingredients = \nnew Dictionary&lt;string, string&gt;();\n      public void Add(string type, string name)\n      {\n        _ingredients[type] = name;\n      }\n      public string Get(string type)\n      {\n        return _ingredients.ContainsKey(type) ? _ingredients[type] : null;\n      }\n      public bool Has(string type, string name)\n      {\n        return name == null ? false : this.Get(type) == name;\n      }\n    }\n\n    public Potion(string name) : this(name, new IngredientBag())    {    }\n</code></pre>\n\n<p>Then, if you have the query parameters in this structure...</p>\n\n<pre><code>Dictionary&lt;string, List&lt;string&gt;&gt; ingredients;\n</code></pre>\n\n<p>You can write the query like this.</p>\n\n<pre><code>from p in Potions\nwhere ingredients.Any(i =&gt; i.Value.Any(v =&gt; p.IngredientBag.Has(i.Key, v))\nselect p;\n</code></pre>\n\n<p>PS, why readonly?</p>\n'}, {'answer_id': 67617, 'author': 'Steve Cooper', 'author_id': 6722, 'author_profile': 'https://Stackoverflow.com/users/6722', 'pm_score': 3, 'selected': False, 'text': '<p>Have you considered <a href="http://en.wikipedia.org/wiki/Memoization" rel="noreferrer">Memoization</a>? </p>\n\n<p>The basic idea is this; if you have an expensive function call, there is a function which will calculate the expensive value on first call, but return a cached version thereafter. The function looks like this;</p>\n\n<pre><code>static Func&lt;T&gt; Remember&lt;T&gt;(Func&lt;T&gt; GetExpensiveValue)\n{\n    bool isCached= false;\n    T cachedResult = default(T);\n\n    return () =&gt;\n    {\n        if (!isCached)\n        {\n            cachedResult = GetExpensiveValue();\n            isCached = true;\n        }\n        return cachedResult;\n\n    };\n}\n</code></pre>\n\n<p>This means you can write this;</p>\n\n<pre><code>    // here\'s something that takes ages to calculate\n    Func&lt;string&gt; MyExpensiveMethod = () =&gt; \n    { \n        System.Threading.Thread.Sleep(5000); \n        return "that took ages!"; \n    };\n\n    // and heres a function call that only calculates it the once.\n    Func&lt;string&gt; CachedMethod = Remember(() =&gt; MyExpensiveMethod());\n\n    // only the first line takes five seconds; \n    // the second and third calls are instant.\n    Console.WriteLine(CachedMethod());\n    Console.WriteLine(CachedMethod());\n    Console.WriteLine(CachedMethod());\n</code></pre>\n\n<p>As a general strategy, it might help.</p>\n'}, {'answer_id': 69701, 'author': 'Fake Jim', 'author_id': 6199, 'author_profile': 'https://Stackoverflow.com/users/6199', 'pm_score': 1, 'selected': False, 'text': "<p>Well, in this case, if you can't use Memoization, you're rather restricted since you can really only use the stack as your cache: You've got no way to declare a new variable at the scope you'll need. All I can think of (and I'm not claiming it will be pretty) that will do what you want but retain the composability you need would be something like...</p>\n\n<pre><code>private static bool TestWith&lt;T&gt;(T cached, Func&lt;T, bool&gt; predicate)\n{\n    return predicate(cached);\n}\n\npublic static Expression&lt;Func&lt;Potion, bool&gt;&gt;\n                ContainsIngredients(string ingredientType, params string[] ingredients)\n{\n    var predicate = PredicateBuilder.False&lt;Potion&gt;();\n    // Here, I'm accessing p.Ingredients several times in one \n    // expression.  Is there any way to cache this value and\n    // reference the cached value in the expression?\n    foreach (var ingredient in ingredients)\n    {\n        var temp = ingredient;\n        predicate = predicate.Or (\n            p =&gt; TestWith(p.Ingredients,\n                i =&gt; i != null &amp;&amp;\n                     i.Contains(ingredientType) &amp;&amp;\n                     i.Get(ingredientType).Contains(temp));\n    }\n\n    return predicate;\n}\n</code></pre>\n\n<p>You could combine together the results from multiple TestWith calls into a more complex boolean expression where required - caching the appropriate expensive value with each call - or you can nest them within the lambdas passed as the second parameter to deal with your complex deep hierarchies.</p>\n\n<p>It would be quite hard to read code though and since you might be introducing a bunch more stack transitions with all the TestWith calls, whether it improves performance would depend on just how expensive your ExpensiveCall() was.</p>\n\n<p>As a note, there won't be any inlining in the original example as suggested by another answer since the expression compiler doesn't do that level of optimisation as far as I know.</p>\n"}]
['https://Stackoverflow.com/questions/66382', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/9825/']