Saving a pointer to a method parameter for later reuse

Similar to how lambda expressions work with free variables, I would like to implement my own closure class, which captures some method parameter.

public class Closure<TObject, TVariable>
{
    public TVariable Variable { get; set; }
    public Func<TObject, bool> Predicate { get; set; }
}

Then I have a class that works with instances DateTime. One method that this closure class should use is as follows:

// Original Version
public IEnumerable<Item> GetDayData(DateTime day)
{
    this.items.Where(i => i.IsValidForDay(day));
}

I would like to convert it to a class Closure. The problem is that I would like to reuse (for performance reasons) my class instance Closure:

private Closure<Item, DateTime> closure = null;
public IEnumerable<Item> GetDayData(DateTime day)
{
    if (closure == null)
    {
        this.closure = new Closure<Item, DateTime>() {
            Variable = reference of "day" param, <=== HOW ????????
            Predicate = i => i.IsValidForDay(this.closure.Variable)
        }
    }
    this.items.Where(this.closure.Predicate);
}

Closure, ( Variable), . , , Variable, , .

?

, , lambda . ( Reflector), , , , ...

+5
3

( , , , / ):

private Closure<Item, DateTime> closure = null;
public IEnumerable<Item> GetDayData(DateTime day)
{
    if (closure == null)
    {
        this.closure = new Closure<Item, DateTime>() {
            Predicate = i => i.IsValidForDay(this.closure.Variable)
        }
    }
    // assign here, else you only capture it the first time
    closure.Variable = day;
    this.items.Where(this.closure.Predicate);
}
0

, .

, . , #, CLR.

, . - , :

public class Closure<TObject, TVariable>
{
    public TVariable Variable { get; set; }
    public Func<TVariable, TObject, bool> OpenPredicate { get; set; }

    public bool ClosedPredicate(TObject o)
    {
      return OpenPredicate(this, o);
    }
}

private Closure<Item, DateTime> closure = null;
public IEnumerable<Item> GetDayData(DateTime day)
{
    if (closure == null)
    {
        this.closure = new Closure<Item, DateTime>() {
            OpenPredicate = (closure, i) => i.IsValidForDay(closure.Variable)
        }
    }
    closure.Variable=day;
    this.items.Where(this.closure.ClosedPredicate);
}

, - . , LINQ . , . LINQ 2-3 .

:

  • items.GetEumerator() , .
  • Where IEnumerable
  • Enumerator.

, , .

0
        List<PicInfo> pi = new List<PicInfo>();
        pi.Add(new PicInfo() { fileName = "a" });
        pi.Add(new PicInfo() { fileName = "a" });
        pi.Add(new PicInfo() { fileName = "b" });
        pi.Add(new PicInfo() { fileName = "b" });
        pi.Add(new PicInfo() { fileName = "a" });            

        string a = "a";
        Closure<PicInfo, string> cl = null;
        cl = new Closure<PicInfo, string>() { 
                  Variable = a, 
                  predicate = (i => i.fileName == cl.Variable.ToString()) 
        };
        MessageBox.Show(pi.Where(cl.predicate).Count().ToString()); // shows 3
        // Change variable value here
        string b = "b";
        cl.Variable = b;
        MessageBox.Show(pi.Where(cl.predicate).Count().ToString()); // Shows 2

@Robert Koritnik, , with your existing class. , Variable

-1

All Articles