(0) exportieren Drucken
Alle erweitern

ParameterBuilder-Klasse

Erstellt Parameterinformationen oder ordnet diese zu.

Namespace: System.Reflection.Emit
Assembly: mscorlib (in mscorlib.dll)

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

Parameterattribute müssen mit der Methodensignatur konsistent sein. Wenn Sie für einen Parameter Out-Attribute angeben, sollten Sie sich vergewissern, dass Typ des Methodenparameters ein ByRef-Typ ist.

Bei einigen ParameterBuilder-Attributen müssen Sie DefineMethod mit infrage kommenden Parametern aufrufen, damit MSIL (Microsoft Intermediate Language) zur Laufzeit ordnungsgemäß eingesetzt werden kann. Wenn Sie z. B. einen ParameterBuilder mit ParameterAttributes.Out für den Parameter 1 von MethodBuilder definieren, dann muss der Parameter 1 von MethodBuilder ein Verweis der Art Type.GetType("System.String&") sein, und nicht Type.GetType("System.String").

Das folgende Beispiel veranschaulicht das Erstellen einer dynamischen Methode mit einem als Verweis übergebenen Parameter unter Verwendung von 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

Alle öffentlichen statischen (Shared in Visual Basic) Member dieses Typs sind threadsicher. Bei Instanzmembern ist die Threadsicherheit nicht gewährleistet.

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

.NET Framework unterstützt nicht alle Versionen sämtlicher Plattformen. Eine Liste der unterstützten Versionen finden Sie unter Systemanforderungen.

.NET Framework

Unterstützt in: 2.0, 1.1, 1.0
Anzeigen:
© 2014 Microsoft