Как вызвать динамический метод для возврата квадрата числа?

Я хочу создать простой динамический метод, который возвращает квадрат целого числа (т. Е. - если число равно 5, оно должно возвращать 25).
Я написал код ниже:-

class Square
{
    public int CalculateSquare(int value)
    { return value * value; }
}
public class DynamicMethodExample
{
    private delegate int SquareDelegate(int value);
    internal void CreateDynamicMethod()
    {

        MethodInfo getSquare = typeof(Square).GetMethod("CalculateSquare");

        DynamicMethod calculateSquare = new DynamicMethod("CalculateSquare",
            typeof(int),new Type[]{typeof(int)});


        ILGenerator il = calculateSquare.GetILGenerator();
        // Load the first argument, which is a integer, onto the stack.
        il.Emit(OpCodes.Ldarg_0);
        il.Emit(OpCodes.Mul);
        // Call the overload of CalculateSquare that returns the square of number
        il.EmitCall(OpCodes.Call, getSquare,null);            
        il.Emit(OpCodes.Ret);



        SquareDelegate hi =
        (SquareDelegate)calculateSquare.CreateDelegate(typeof(SquareDelegate));

        Console.WriteLine("\r\nUse the delegate to execute the dynamic method:");
        int retval = hi(42);
        Console.WriteLine("Calculate square returned " + retval);
    }
}

Почему я получаю "InvalidProgramException" в

int retval = hi(42);

Как я могу заставить эту вещь работать?

1 ответ

Решение

У вас есть пара вопросов. Во-первых, класс Square должен быть открытым, а метод CalculateSquare должен быть статическим. Во-вторых, вы не хотите испускать Mul, если вы вызываете метод умножения. Вот ваш код с этими исправлениями:

public class Square
{
    public static int CalculateSquare( int value )
    { return value * value; }
}

public class DynamicMethodExample
{
    private delegate int SquareDelegate( int value );

    internal void CreateDynamicMethod()
    {

        MethodInfo getSquare = typeof( Square ).GetMethod( "CalculateSquare" );

        DynamicMethod calculateSquare = new DynamicMethod( "CalculateSquare",
            typeof( int ), new Type[] { typeof( int ) } );


        ILGenerator il = calculateSquare.GetILGenerator();
        // Load the first argument, which is a integer, onto the stack.
        il.Emit( OpCodes.Ldarg_0 );
        // Call the overload of CalculateSquare that returns the square of number
        il.Emit( OpCodes.Call, getSquare );
        il.Emit( OpCodes.Ret );



        SquareDelegate hi =
        ( SquareDelegate )calculateSquare.CreateDelegate( typeof( SquareDelegate ) );

        Console.WriteLine( "\r\nUse the delegate to execute the dynamic method:" );
        int retval = hi( 42 );
        Console.WriteLine( "Calculate square returned " + retval );

    }
}
Другие вопросы по тегам