¿Cómo crear un delegado vacío usando árboles de expresiones?

c# delegates events expression-trees

Pregunta

Usando métodos anónimos puedes crear delegados vacíos desde C # 2.0.

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

Esto es útil, por ejemplo, para evitar tener que realizar la comprobación nula al invocar eventos .

¿Cómo puedo crear el mismo comportamiento usando árboles de expresiones ?

La única opción posible que veo ahora es usar Expression.Lambda() , pero por lo que puedo decir, esto requeriría mucho trabajo adicional.

Respuesta aceptada

Pues resulta que no es que mucho trabajo usando Expression.Lambda() . Sin embargo, todavía estoy interesado en otras posibles respuestas.

Necesitaba un método auxiliar que escribí anteriormente:

/// <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 );
}

Cuando tenga EventInfo , puede crear un lambda vacío para él de la siguiente manera:

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();

Respuesta popular

Un árbol de expresiones, por la naturaleza de su propósito, siempre tiene una expresión para un cuerpo en lugar de una declaración en el diseño original.

En C # 3 no había manera de expresar un árbol de expresiones cuyo cuerpo es un bloque de declaración vacío. Más recientemente, la biblioteca del árbol de expresiones se ha ampliado para permitir sentencias, pero las reglas de análisis semántico de C # no se actualizaron para aprovechar eso; todavía no puede convertir una declaración lambda en un árbol de expresión.



Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow