Comment créer un délégué vide en utilisant des arbres d'expression?

c# delegates events expression-trees

Question

En utilisant des méthodes anonymes, vous pouvez créer des délégués vides depuis C # 2.0.

public event EventHandler SomeEvent = delegate {};
public event Action OtherEvent = delegate {};

C'est par exemple utile pour éviter d'avoir à effectuer la vérification de la valeur NULL lors de l'appel d'événements .

Comment créer le même comportement à l'aide des arbres d'expression ?

La seule option possible que je vois maintenant est d'utiliser Expression.Lambda() , mais autant que je sache, cela nécessiterait beaucoup de travail supplémentaire.

Réponse acceptée

Il s'avère que travailler avec Expression.Lambda() ne demande pas beaucoup de travail. Cependant, je suis toujours intéressé par d'autres réponses possibles.

J'ai eu besoin d'une méthode d'assistance que j'avais écrite précédemment:

/// <summary>
///   The name of the Invoke method of a Delegate.
/// </summary>
const string InvokeMethod = "Invoke";

/// <summary>
///   Get method info for a specified delegate type.
/// </summary>
/// <param name = "delegateType">The delegate type to get info for.</param>
/// <returns>The method info for the given delegate type.</returns>
public static MethodInfo MethodInfoFromDelegateType( Type delegateType )
{
    Contract.Requires(
        delegateType.IsSubclassOf( typeof( MulticastDelegate ) ),
        "Given type should be a delegate." );

    return delegateType.GetMethod( InvokeMethod );
}

Lorsque vous avez EventInfo vous pouvez créer un lambda vide comme suit:

EventInfo _event;

...

MethodInfo delegateInfo
    = DelegateHelper.MethodInfoFromDelegateType( _event.EventHandlerType );
ParameterExpression[] parameters = delegateInfo
    .GetParameters()
    .Select( p => Expression.Parameter( p.ParameterType ) )
    .ToArray();
Delegate emptyDelegate = Expression.Lambda(
    _event.EventHandlerType,
    Expression.Empty(), "EmptyDelegate", true, parameters ).Compile();

Réponse populaire

Un arbre d'expression, de par sa nature même, a toujours pour expression un corps plutôt qu'une déclaration dans le dessin d'origine.

En C # 3, il n'y avait aucun moyen d'exprimer un arbre d'expression dont le corps était un bloc d'instructions vide. Plus récemment, la bibliothèque d'arborescence d'expression a été étendue pour autoriser les instructions, mais les règles d'analyse sémantique C # n'ont pas été mises à jour pour en tirer parti. vous ne pouvez toujours pas transformer une déclaration lambda en un arbre d'expression.




Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi