Exportar (0) Imprimir
Expandir todo

ParameterBuilder (Clase)

Actualización: noviembre 2007

Crea o asocia información de parámetros.

Espacio de nombres:  System.Reflection.Emit
Ensamblado:  mscorlib (en mscorlib.dll)

[ClassInterfaceAttribute(ClassInterfaceType.None)]
[ComVisibleAttribute(true)]
public class ParameterBuilder : _ParameterBuilder
/** @attribute ClassInterfaceAttribute(ClassInterfaceType.None) */
/** @attribute ComVisibleAttribute(true) */
public class ParameterBuilder implements _ParameterBuilder
public class ParameterBuilder implements _ParameterBuilder

Los atributos de parámetros deben ser coherentes con la firma del método. Si se especifican los atributos Out para un parámetro, hay que asegurarse de que el tipo de ese parámetro del método es ByRef.

Algunos atributos ParameterBuilder necesitan que se llame a DefineMethod con parámetros viables de forma que el lenguaje intermedio de Microsoft (MSIL) funcione correctamente en tiempo de ejecución. Por ejemplo, si se define ParameterBuilder con ParameterAttributes.Out para el parámetro 1 de MethodBuilder, el parámetro 1 de MethodBuilder deberá ser una referencia como Type.GetType("System.String&"), en lugar de Type.GetType("System.String").

En el siguiente ejemplo se muestra cómo crear un método dinámico con un parámetro pasado por referencia mediante ParameterBuilder.


using System;
using System.Threading;
using System.Reflection;
using System.Reflection.Emit;

class ParamBuilderDemo 

{

   public static Type BuildCustomerDataType()
   {

	AppDomain myDomain = Thread.GetDomain();
	AssemblyName myAsmName = new AssemblyName();
	myAsmName.Name = "MyDynamicAssembly";

	AssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly(myAsmName,
						AssemblyBuilderAccess.Run);

	ModuleBuilder myModBuilder = myAsmBuilder.DefineDynamicModule("MyMod");

	TypeBuilder myTypeBuilder = myModBuilder.DefineType("CustomerData",
						TypeAttributes.Public);

	FieldBuilder customerNameBldr = myTypeBuilder.DefineField("customerName",
							typeof(string),
							FieldAttributes.Private);
	FieldBuilder acctIDBldr = myTypeBuilder.DefineField("acctID",
						 	typeof(string),
							FieldAttributes.Private);
	FieldBuilder balanceAmtBldr = myTypeBuilder.DefineField("balanceAmt",
							typeof(double),
							FieldAttributes.Private);
								
	ConstructorBuilder myCtorBuilder = myTypeBuilder.DefineConstructor(
							MethodAttributes.Public,
							CallingConventions.HasThis, 
							new Type[] { typeof(string),
								     typeof(string),
								     typeof(double) });


	ILGenerator ctorIL = myCtorBuilder.GetILGenerator();

	Type objType = Type.GetType("System.Object"); 
        ConstructorInfo objCtor = objType.GetConstructor(new Type[] {});

	ctorIL.Emit(OpCodes.Ldarg_0);
	ctorIL.Emit(OpCodes.Call, objCtor);

	ctorIL.Emit(OpCodes.Ldarg_0);
	ctorIL.Emit(OpCodes.Ldarg_1);
	ctorIL.Emit(OpCodes.Stfld, customerNameBldr);

	ctorIL.Emit(OpCodes.Ldarg_0);
	ctorIL.Emit(OpCodes.Ldarg_2);
	ctorIL.Emit(OpCodes.Stfld, acctIDBldr);

	ctorIL.Emit(OpCodes.Ldarg_0);
	ctorIL.Emit(OpCodes.Ldarg_3);
	ctorIL.Emit(OpCodes.Stfld, balanceAmtBldr);

	ctorIL.Emit(OpCodes.Ret);

	// This method will take an amount from a static pool and add it to the balance.

	// Note that we are passing the first parameter, fundsPool, by reference. Therefore,
	// we need to inform the MethodBuilder to expect a ref, by declaring the first
	// parameter's type to be System.Double& (a reference to a double).

	MethodBuilder myMthdBuilder = myTypeBuilder.DefineMethod("AddFundsFromPool",
						MethodAttributes.Public,
						typeof(double),
						new Type[] { Type.GetType("System.Double&"),
							     typeof(double) });

	ParameterBuilder poolRefBuilder = myMthdBuilder.DefineParameter(1,
						ParameterAttributes.Out,
						"fundsPool");

	ParameterBuilder amountFromPoolBuilder = myMthdBuilder.DefineParameter(2,
						ParameterAttributes.In,
					        "amountFromPool");

	ILGenerator mthdIL = myMthdBuilder.GetILGenerator();

	mthdIL.Emit(OpCodes.Ldarg_1); 
	mthdIL.Emit(OpCodes.Ldarg_1); 
	mthdIL.Emit(OpCodes.Ldind_R8);
	mthdIL.Emit(OpCodes.Ldarg_2);
	mthdIL.Emit(OpCodes.Sub);

	mthdIL.Emit(OpCodes.Stind_R8);

	mthdIL.Emit(OpCodes.Ldarg_0);
	mthdIL.Emit(OpCodes.Ldarg_0);
	mthdIL.Emit(OpCodes.Ldfld, balanceAmtBldr);
	mthdIL.Emit(OpCodes.Ldarg_2);
	mthdIL.Emit(OpCodes.Add);

	mthdIL.Emit(OpCodes.Stfld, balanceAmtBldr);

	mthdIL.Emit(OpCodes.Ldarg_0);
	mthdIL.Emit(OpCodes.Ldfld, balanceAmtBldr);
	mthdIL.Emit(OpCodes.Ret);

	return myTypeBuilder.CreateType();

   }

   public static void Main()
   {
 	Type custType = null;
	object custObj = null;

	Type[] custArgTypes = new Type[] {typeof(string), typeof(string), typeof(double)};
	
	// Call the method to build our dynamic class.

	custType = BuildCustomerDataType();

	Console.WriteLine("---");

	ConstructorInfo myCustCtor = custType.GetConstructor(custArgTypes);
	double initialBalance = 100.00;
	custObj = myCustCtor.Invoke(new object[] { "Joe Consumer", 
						   "5678-XYZ", 
					  	   initialBalance });

	MemberInfo[] myMemberInfo = custType.GetMember("AddFundsFromPool");


	double thePool = 1000.00;
	Console.WriteLine("The pool is currently ${0}", thePool);
	Console.WriteLine("The original balance of the account instance is ${0}",
							initialBalance);

	double amountFromPool = 50.00;
	Console.WriteLine("The amount to be subtracted from the pool and added " +
			  "to the account is ${0}", amountFromPool);
	
	Console.WriteLine("---");
	Console.WriteLine("Calling {0} ...", myMemberInfo[0].ToString());
	Console.WriteLine("---");

	object[] passMe = new object[] { thePool, amountFromPool };
	Console.WriteLine("The new balance in the account instance is ${0}",
					custType.InvokeMember("AddFundsFromPool",
					BindingFlags.InvokeMethod,
					null, custObj, passMe));
	thePool = (double)passMe[0];
	Console.WriteLine("The new amount in the pool is ${0}", thePool);

   }

}



import System.*;
import System.Threading.*;
import System.Reflection.*;
import System.Reflection.Emit.*;

class ParamBuilderDemo
{
    public static Type BuildCustomerDataType() 
    {
        AppDomain myDomain = System.Threading.Thread.GetDomain();
        AssemblyName myAsmName = new AssemblyName();
        myAsmName.set_Name("MyDynamicAssembly");
        AssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly
            (myAsmName, AssemblyBuilderAccess.Run);
        ModuleBuilder myModBuilder = myAsmBuilder.DefineDynamicModule("MyMod");
        TypeBuilder myTypeBuilder = myModBuilder.DefineType("CustomerData",
            TypeAttributes.Public);
        FieldBuilder customerNameBldr = myTypeBuilder.DefineField
            ("customerName", String.class.ToType(), FieldAttributes.Private);
        FieldBuilder acctIDBldr = myTypeBuilder.DefineField("acctID",
            String.class.ToType(), FieldAttributes.Private);
        FieldBuilder balanceAmtBldr = myTypeBuilder.DefineField("balanceAmt",
            double.class.ToType(), FieldAttributes.Private);
          ConstructorBuilder myCtorBuilder = myTypeBuilder.DefineConstructor
            (MethodAttributes.Public, CallingConventions.HasThis,
            new Type[]{String.class.ToType(), String.class.ToType(),
            double.class.ToType()});
        ILGenerator ctorIL = myCtorBuilder.GetILGenerator();
        Type objType = Type.GetType("System.Object");
        ConstructorInfo objCtor = objType.GetConstructor(new Type[]{});
        ctorIL.Emit(OpCodes.Ldarg_0);
        ctorIL.Emit(OpCodes.Call, objCtor);
        ctorIL.Emit(OpCodes.Ldarg_0);
        ctorIL.Emit(OpCodes.Ldarg_1);
        ctorIL.Emit(OpCodes.Stfld, customerNameBldr);
        ctorIL.Emit(OpCodes.Ldarg_0);
        ctorIL.Emit(OpCodes.Ldarg_2);
        ctorIL.Emit(OpCodes.Stfld, acctIDBldr);
        ctorIL.Emit(OpCodes.Ldarg_0);
        ctorIL.Emit(OpCodes.Ldarg_3);
        ctorIL.Emit(OpCodes.Stfld, balanceAmtBldr);
        ctorIL.Emit(OpCodes.Ret);

        // This method will take an amount from a static pool and add it
        // to the balance. Note that we are passing the first parameter,
        //fundsPool, by reference. Therefore,we need to inform the
        // MethodBuilder to expect a ref, by declaring the first
        // parameter's type to be System.Double& (a reference to a double).
        MethodBuilder myMthdBuilder = myTypeBuilder.DefineMethod
            ("AddFundsFromPool", MethodAttributes.Public,
            double.class.ToType(),
            new Type[]{Type.GetType("System.Double&"),
            double.class.ToType()});
        ParameterBuilder poolRefBuilder = myMthdBuilder.DefineParameter(1,
            ParameterAttributes.Out, "fundsPool");
        ParameterBuilder amountFromPoolBuilder = 
            myMthdBuilder.DefineParameter(2, ParameterAttributes.In,
            "amountFromPool");
        ILGenerator mthdIL = myMthdBuilder.GetILGenerator();
        mthdIL.Emit(OpCodes.Ldarg_1);
        mthdIL.Emit(OpCodes.Ldarg_1);
        mthdIL.Emit(OpCodes.Ldind_R8);
        mthdIL.Emit(OpCodes.Ldarg_2);
        mthdIL.Emit(OpCodes.Sub);
        mthdIL.Emit(OpCodes.Stind_R8);
        mthdIL.Emit(OpCodes.Ldarg_0);
        mthdIL.Emit(OpCodes.Ldarg_0);
        mthdIL.Emit(OpCodes.Ldfld, balanceAmtBldr);
        mthdIL.Emit(OpCodes.Ldarg_2);
        mthdIL.Emit(OpCodes.Add);
        mthdIL.Emit(OpCodes.Stfld, balanceAmtBldr);
        mthdIL.Emit(OpCodes.Ldarg_0);
        mthdIL.Emit(OpCodes.Ldfld, balanceAmtBldr);
        mthdIL.Emit(OpCodes.Ret);

        return myTypeBuilder.CreateType() ;
    } //BuildCustomerDataType

    public static void main(String[] args)
    {
        Type custType = null;
        Object custObj = null;
        Type custArgTypes[] = new Type[]{String.class.ToType(),
            String.class.ToType(), double.class.ToType()};

        // Call the method to build our dynamic class.
        custType = BuildCustomerDataType();
        Console.WriteLine("---");
        ConstructorInfo myCustCtor = custType.GetConstructor(custArgTypes);
        double initialBalance = 100.0;
        custObj = myCustCtor.Invoke(new Object[]{"Joe Consumer", "5678-XYZ",
            (System.Double)(initialBalance)});
        MemberInfo myMemberInfo[] = custType.GetMember("AddFundsFromPool");

        double thePool = 1000.0;
        Console.WriteLine("The pool is currently ${0}",
            System.Convert.ToString(thePool));
        Console.WriteLine(
            "The original balance of the account instance is ${0}",
            new Object[] { (System.Double)(initialBalance) });

        double amountFromPool = 50.0;
        Console.WriteLine("The amount to be subtracted from the pool and added"
            + " to the account is ${0}", (System.Double)(amountFromPool));
        Console.WriteLine("---");
        Console.WriteLine("Calling {0} ...",
            myMemberInfo .get_Item( 0).ToString());
        Console.WriteLine("---");
        Object passMe[] = new Object[] { (System.Double)(thePool),
            (System.Double)(amountFromPool) };
        Console.WriteLine("The new balance in the account instance is ${0}",
            custType.InvokeMember("AddFundsFromPool",
            BindingFlags.InvokeMethod, null, custObj, passMe));
        thePool = (double)Double.parseDouble(passMe[0].toString());
        Console.WriteLine("The new amount in the pool is ${0}",
            (System.Double)(thePool));
    } //main 
} //ParamBuilderDemo


System.Object
  System.Reflection.Emit.ParameterBuilder

Todos los miembros static (Shared en Visual Basic) públicos de este tipo son seguros para la ejecución de subprocesos. No se garantiza que los miembros de instancias sean seguros para la ejecución de subprocesos.

Windows Vista, Windows XP SP2, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP Starter Edition, Windows Server 2003, Windows Server 2000 SP4, Windows Millennium Edition, Windows 98

.NET Framework y .NET Compact Framework no admiten todas las versiones de cada plataforma. Para obtener una lista de las versiones compatibles, vea Requisitos de sistema de .NET Framework.

.NET Framework

Compatible con: 3.5, 3.0, 2.0, 1.1, 1.0

Adiciones de comunidad

AGREGAR
Mostrar:
© 2014 Microsoft