la conversion d'un .net Func<T> pour un .net de l'Expression<Func<T>>

À partir d'un lambda à une Expression est facile à l'aide d'un appel de méthode...

public void GimmeExpression(Expression<Func<T>> expression)
{
    ((MemberExpression)expression.Body).Member.Name; //"DoStuff"
}

public void SomewhereElse()
{
    GimmeExpression(() => thing.DoStuff());
}

Mais je voudrais tourner la touche Func dans une expression, dans de rares cas seulement...

public void ContainTheDanger(Func<T> dangerousCall)
{
    try 
    {
        dangerousCall();
    }
    catch (Exception e)
    {
        //This next line does not work...
        Expression<Func<T>> DangerousExpression = dangerousCall;
        var nameOfDanger = 
            ((MemberExpression)dangerousCall.Body).Member.Name;
        throw new DangerContainer(
            "Danger manifested while " + nameOfDanger, e);
    }
}

public void SomewhereElse()
{
    ContainTheDanger(() => thing.CrossTheStreams());
}

La ligne qui n'a pas de travail me donne l'erreur de compilation Cannot implicitly convert type 'System.Func<T>' to 'System.Linq.Expressions.Expression<System.Func<T>>'. Un cast explicite ne permet pas de résoudre la situation. Est-il de la facilité à faire ce que je suis dominant?

  • Je ne vois vraiment pas beaucoup utiliser pour le "cas rare" de l'exemple. L'appelant est en passant la touche Func<T>. Il n'est pas nécessaire de répéter à l'appelant de ce que Func<T> a (via l'exception).
  • L'exception n'est pas gérée en l'appelant. Et, parce qu'il y a de multiples sites d'appel en passant dans les différents Func<T>s, la capture de l'exception en l'appelant crée la duplication.
  • La trace de pile d'exception est conçu pour montrer cette information. Si l'exception est levée dans l'invocation de la touche Func<T>, cela montrera dans la trace de la pile. D'ailleurs, si vous choisissez d'aller dans l'autre sens, c'est à dire accepter une expression et le compiler pour l'invocation, vous perdez ce depuis la trace de pile serait montrer quelque chose comme at lambda_method(Closure ) pour l'invocation de l'compilé délégué.
  • Je suppose que vous devriez regarder la réponse dans ce [lien][1] [1]: stackoverflow.com/questions/9377635/create-expression-from-func/...
InformationsquelleAutor Dave Cameron | 2009-04-20