Компиляция лямбда-выражения приводит к делегату с аргументом Closure

Когда я использую Expression.Lambda (...) .Compile () для создания делегата из дерева выражений, результат является делегатом, первым аргументом которого является Closure .

public static Func CreateTest()
{
    ParameterExpression a = Expression.Parameter( typeof( T ) );
    ParameterExpression b = Expression.Parameter( typeof( T ) );
    Expression addition = Expression.Add( a, b );

    return (Func)Expression.Lambda( addition, a, b ).Compile();
}

...

// 'addition' equals
// Int32 lambda_method(
//     System.Runtime.CompilerServices.Closure,
//     Int32,
//     Int32 )
Func addition = DelegateHelper.CreateTest();
int result = addition( 5, 5 );

Я могу легко вызвать делегата через обычный код, не передавая объект Closure , но откуда взялось это Closure ?

Как я могу вызвать этот делегат динамически?

// The following does not work.
// Exception: MethodInfo must be a runtime MethodInfo object.    
MethodInfo additionMethod = addition.Method;
int result = (int)additionMethod.Invoke( null, new object[] { 5, 5 } );

​​Используя деревья выражений, похоже, что мне нужно передать объект Closure .

PropertyInfo methodProperty
    = typeof( Delegate ).GetProperty( "Method", typeof( MethodInfo ) );
MemberExpression getDelegateMethod
    = Expression.Property( Expression.Constant( addition ), methodProperty );
Func getMethodInfo
    = (Func)Expression.Lambda( getDelegateMethod ).Compile();
// Incorrect number of arguments supplied for call to method
// 'Int32 lambda_method(System.Runtime.CompilerServices.Closure, Int32, Int32)'
Expression call
    = Expression.Call(
        getMethodInfo(),
        Expression.Constant( 5 ), Expression.Constant( 5 ) );

Это упрощенный пример, который сам по себе не имеет смысла. То, что я на самом деле пытаюсь достичь, - это возможность обернуть, например. Func > с Func > . Я уже могу сделать это для невложенных делегатов. Это полезно во время отражения, , как обсуждается здесь .

Как мне правильно инициализировать этот объект Closure или как предотвратить его присутствие?

13
задан Steven Jeuris 29 October 2011 в 15:07
поделиться