Obțineți Func <T> și Expresia <Func <T >> de la un singur parametru?

Aș dori să obțin atât Func compilat (de boolean), cât și un Expresie (de Func (boolean)) utilizând un singur parametru. Nu intenționez să modific arborele expresiei. Singurul motiv pentru a face un copac de expresie deloc este așa că pot imprima codul care se execută.

void Assert(Expression> assertionExpression) {
    if (!assertionExpression.Compile()()) 
    { 
        throw new AssertFailedException(assertionExpression.ToString()); 
    }
}

Există vreo modalitate rezonabilă de a face acest lucru?

Ca o corrolarrie, în cazul copacilor de expresie generați de compilatorul simplu, aceeași instanță va fi întotdeauna trecută ca parametru?

static Dictionary>, Func> cache;

static void Assert(Expression> assertionExpression) {
    Func method = null;
    if (!cache.TryGetValue(assertionExpression, out method)) {
        cache.Add(assertionExpression, method = assertionExpression.Compile());
        Console.WriteLine("cache insert");
    }
    else {
         Console.WriteLine("cache hit");
    }
    if (!method()) 
    { 
        throw new AssertFailedException(assertionExpression.ToString()); 
    }
}

static void someCodeThatExecutesRegularly() {
    Assert(()=>true);
}

public static void Main(string[] args, int argc) 
{
    someCodeThatExecutesRegularly();

    someCodeThatExecutesRegularly();

    someCodeThatExecutesRegularly();
}

Va fi ieșirea "inserați cache," cache hit "," cache hit "sau" insert cache "," insert cache "," insert cache ".

0

1 răspunsuri

Pentru prima întrebare, puteți să luați arborele de expresie și să îl compilați pentru a obține o versiune executabilă, deși se va recompila de fiecare dată, astfel încât va trebui să o memorați în cache.

static void Assert(Expression> assertionExpression) {
    var func = assertionExpression.Compile();//if you call func() it will execute the expression
}

Pentru cea de-a doua întrebare, va fi un arbore de expresie nou de fiecare dată, așa că veți primi "cache insert" "insert cache" "insert cache" etc ...

Pentru a-l lucra cu cache-ul și compilarea ar putea fi posibil să utilizați .ToString() pe expresie pentru a obține reprezentarea șirului funcției, dar acest lucru ar putea provoca probleme foarte confuze dacă aveți închideri deoarece reprezentarea șirului ar putea fi aceeași, dar variabilele închise ar fi diferite, deci dacă faceți acest lucru, UTILIZEAZĂ-ȚI CU CARE!

0
adăugat