AssemblyBuilder.Save AssemblyBuilder.Save AssemblyBuilder.Save AssemblyBuilder.Save Method

Definición

Guarda en disco este ensamblado dinámico.Saves this dynamic assembly to disk.

Sobrecargas

Save(String) Save(String) Save(String) Save(String)

Guarda en disco este ensamblado dinámico.Saves this dynamic assembly to disk.

Save(String, PortableExecutableKinds, ImageFileMachine) Save(String, PortableExecutableKinds, ImageFileMachine) Save(String, PortableExecutableKinds, ImageFileMachine)

Guarda este ensamblado dinámico en disco, especificando la naturaleza del código en los ejecutables del ensamblado y la plataforma de destino.Saves this dynamic assembly to disk, specifying the nature of code in the assembly's executables and the target platform.

Save(String) Save(String) Save(String) Save(String)

Guarda en disco este ensamblado dinámico.Saves this dynamic assembly to disk.

public:
 void Save(System::String ^ assemblyFileName);
public void Save (string assemblyFileName);
member this.Save : string -> unit
Public Sub Save (assemblyFileName As String)

Parámetros

assemblyFileName
String String String String

El nombre de archivo del ensamblado.The file name of the assembly.

Excepciones

La longitud de assemblyFileName es 0.The length of assemblyFileName is 0.

O bien-or- Hay dos o más archivos de recursos de módulos en el ensamblado con el mismo nombre.There are two or more modules resource files in the assembly with the same name.

O bien-or- El directorio de destino del ensamblado no es válido.The target directory of the assembly is invalid.

O bien-or- assemblyFileName no es un nombre de archivo simple (por ejemplo, tiene un componente de directorio o de unidad), o se ha definido más de un recurso no administrado, incluido un recurso de información de versión, en este ensamblado.assemblyFileName is not a simple file name (for example, has a directory or drive component), or more than one unmanaged resource, including a version information resource, was defined in this assembly.

O bien-or- La cadena CultureInfo de AssemblyCultureAttribute no es válida y se ha llamado a DefineVersionInfoResource(String, String, String, String, String) antes de llamar a este método.The CultureInfo string in AssemblyCultureAttribute is not a valid string and DefineVersionInfoResource(String, String, String, String, String) was called prior to calling this method.

assemblyFileName es null.assemblyFileName is null.

Este ensamblado se ha guardado anteriormente.This assembly has been saved before.

O bien-or- Este ensamblado tiene acceso RunAssemblyBuilderAccessThis assembly has access RunAssemblyBuilderAccess

Se produce un error de salida al guardar.An output error occurs during the save.

No se ha llamado a CreateType() para ninguno de los tipos de los módulos del ensamblado que se van a escribir en disco.CreateType() has not been called for any of the types in the modules of the assembly to be written to disk.

Ejemplos

Ejemplo de código siguiente crea un ensamblado dinámico y, a continuación, lo almacena en un disco local mediante Save.The following code sample creates a dynamic assembly and then persists it to a local disk using Save.

using namespace System;
using namespace System::Text;
using namespace System::Threading;
using namespace System::Reflection;
using namespace System::Reflection::Emit;

// The Point class is the class we will reflect on and copy into our
// dynamic assembly. The public static function PointMain() will be used
// as our entry point.
//
// We are constructing the type seen here dynamically, and will write it
// out into a .exe file for later execution from the command-line.
// ---
// __gc class Point {
// 
// private:
//    int  x;
//    int  y;
// 
// public:
//    Point(int ix, int iy) {
// 
//       this->x = ix;
//       this->y = iy;
// 
//    }
// 
//    int DotProduct (Point* p) {
// 
//       return ((this->x * p->x) + (this->y * p->y));
// 
//   }
// 
//    static void PointMain() {
// 
//       Console::Write(S"Enter the 'x' value for point 1: ");
//       int x1 = Convert::ToInt32(Console::ReadLine());
// 
//       Console::Write(S"Enter the 'y' value for point 1: ");
//       int y1 = Convert::ToInt32(Console::ReadLine());
// 
//       Console::Write(S"Enter the 'x' value for point 2: ");
//       int x2 = Convert::ToInt32(Console::ReadLine());
// 
//       Console::Write(S"Enter the 'y' value for point 2: ");
//       int y2 = Convert::ToInt32(Console::ReadLine());
// 
//       Point* p1 = new Point(x1, y1);
//       Point* p2 = new Point(x2, y2);
// 
//       Console::WriteLine(S"( {0}, {1}) . ( {2}, {3}) = {4}.",
//          __box(x1), __box(y1), __box(x2), __box(y2), p1->DotProduct(p2));
// 
//    }
// 
// };
// ---
Type^ BuildDynAssembly()
{
   Type^ pointType = nullptr;
   AppDomain^ currentDom = Thread::GetDomain();
   Console::Write( "Please enter a name for your new assembly: " );
   StringBuilder^ asmFileNameBldr = gcnew StringBuilder;
   asmFileNameBldr->Append( Console::ReadLine() );
   asmFileNameBldr->Append( ".exe" );
   String^ asmFileName = asmFileNameBldr->ToString();
   AssemblyName^ myAsmName = gcnew AssemblyName;
   myAsmName->Name = "MyDynamicAssembly";
   AssemblyBuilder^ myAsmBldr = currentDom->DefineDynamicAssembly( myAsmName, AssemblyBuilderAccess::RunAndSave );
   
   // We've created a dynamic assembly space - now, we need to create a module
   // within it to reflect the type Point into.
   ModuleBuilder^ myModuleBldr = myAsmBldr->DefineDynamicModule( asmFileName, asmFileName );
   TypeBuilder^ myTypeBldr = myModuleBldr->DefineType( "Point" );
   FieldBuilder^ xField = myTypeBldr->DefineField( "x", int::typeid, FieldAttributes::Private );
   FieldBuilder^ yField = myTypeBldr->DefineField( "y", int::typeid, FieldAttributes::Private );
   
   // Build the constructor.
   Type^ objType = Type::GetType( "System.Object" );
   ConstructorInfo^ objCtor = objType->GetConstructor( gcnew array<Type^>(0) );
   array<Type^>^temp4 = {int::typeid,int::typeid};
   array<Type^>^ctorParams = temp4;
   ConstructorBuilder^ pointCtor = myTypeBldr->DefineConstructor( MethodAttributes::Public, CallingConventions::Standard, ctorParams );
   ILGenerator^ ctorIL = pointCtor->GetILGenerator();
   ctorIL->Emit( OpCodes::Ldarg_0 );
   ctorIL->Emit( OpCodes::Call, objCtor );
   ctorIL->Emit( OpCodes::Ldarg_0 );
   ctorIL->Emit( OpCodes::Ldarg_1 );
   ctorIL->Emit( OpCodes::Stfld, xField );
   ctorIL->Emit( OpCodes::Ldarg_0 );
   ctorIL->Emit( OpCodes::Ldarg_2 );
   ctorIL->Emit( OpCodes::Stfld, yField );
   ctorIL->Emit( OpCodes::Ret );
   
   // Build the DotProduct method.
   Console::WriteLine( "Constructor built." );
   array<Type^>^temp0 = {myTypeBldr};
   MethodBuilder^ pointDPBldr = myTypeBldr->DefineMethod( "DotProduct", MethodAttributes::Public, int::typeid, temp0 );
   ILGenerator^ dpIL = pointDPBldr->GetILGenerator();
   dpIL->Emit( OpCodes::Ldarg_0 );
   dpIL->Emit( OpCodes::Ldfld, xField );
   dpIL->Emit( OpCodes::Ldarg_1 );
   dpIL->Emit( OpCodes::Ldfld, xField );
   dpIL->Emit( OpCodes::Mul_Ovf_Un );
   dpIL->Emit( OpCodes::Ldarg_0 );
   dpIL->Emit( OpCodes::Ldfld, yField );
   dpIL->Emit( OpCodes::Ldarg_1 );
   dpIL->Emit( OpCodes::Ldfld, yField );
   dpIL->Emit( OpCodes::Mul_Ovf_Un );
   dpIL->Emit( OpCodes::Add_Ovf_Un );
   dpIL->Emit( OpCodes::Ret );
   
   // Build the PointMain method.
   Console::WriteLine( "DotProduct built." );
   MethodBuilder^ pointMainBldr = myTypeBldr->DefineMethod( "PointMain", static_cast<MethodAttributes>(MethodAttributes::Public | MethodAttributes::Static), void::typeid, nullptr );
   pointMainBldr->InitLocals = true;
   ILGenerator^ pmIL = pointMainBldr->GetILGenerator();
   
   // We have four methods that we wish to call, and must represent as
   // MethodInfo tokens:
   // - void Console::WriteLine(String*)
   // - String* Console::ReadLine()
   // - int Convert::Int32(String*)
   // - void Console::WriteLine(String*, Object*[])
   array<Type^>^temp1 = {String::typeid};
   MethodInfo^ writeMI = Console::typeid->GetMethod( "Write", temp1 );
   MethodInfo^ readLineMI = Console::typeid->GetMethod( "ReadLine", gcnew array<Type^>(0) );
   array<Type^>^temp2 = {String::typeid};
   MethodInfo^ convertInt32MI = Convert::typeid->GetMethod( "ToInt32", temp2 );
   array<Type^>^temp5 = {String::typeid,array<Object^>::typeid};
   array<Type^>^wlParams = temp5;
   MethodInfo^ writeLineMI = Console::typeid->GetMethod( "WriteLine", wlParams );
   
   // Although we could just refer to the local variables by
   // index (short ints for Ldloc/Stloc, bytes for LdLoc_S/Stloc_S),
   // this time, we'll use LocalBuilders for clarity and to
   // demonstrate their usage and syntax.
   LocalBuilder^ x1LB = pmIL->DeclareLocal( int::typeid );
   LocalBuilder^ y1LB = pmIL->DeclareLocal( int::typeid );
   LocalBuilder^ x2LB = pmIL->DeclareLocal( int::typeid );
   LocalBuilder^ y2LB = pmIL->DeclareLocal( int::typeid );
   LocalBuilder^ point1LB = pmIL->DeclareLocal( myTypeBldr );
   LocalBuilder^ point2LB = pmIL->DeclareLocal( myTypeBldr );
   LocalBuilder^ tempObjArrLB = pmIL->DeclareLocal( array<Object^>::typeid );
   pmIL->Emit( OpCodes::Ldstr, "Enter the 'x' value for point 1: " );
   pmIL->EmitCall( OpCodes::Call, writeMI, nullptr );
   pmIL->EmitCall( OpCodes::Call, readLineMI, nullptr );
   pmIL->EmitCall( OpCodes::Call, convertInt32MI, nullptr );
   pmIL->Emit( OpCodes::Stloc, x1LB );
   pmIL->Emit( OpCodes::Ldstr, "Enter the 'y' value for point 1: " );
   pmIL->EmitCall( OpCodes::Call, writeMI, nullptr );
   pmIL->EmitCall( OpCodes::Call, readLineMI, nullptr );
   pmIL->EmitCall( OpCodes::Call, convertInt32MI, nullptr );
   pmIL->Emit( OpCodes::Stloc, y1LB );
   pmIL->Emit( OpCodes::Ldstr, "Enter the 'x' value for point 2: " );
   pmIL->EmitCall( OpCodes::Call, writeMI, nullptr );
   pmIL->EmitCall( OpCodes::Call, readLineMI, nullptr );
   pmIL->EmitCall( OpCodes::Call, convertInt32MI, nullptr );
   pmIL->Emit( OpCodes::Stloc, x2LB );
   pmIL->Emit( OpCodes::Ldstr, "Enter the 'y' value for point 2: " );
   pmIL->EmitCall( OpCodes::Call, writeMI, nullptr );
   pmIL->EmitCall( OpCodes::Call, readLineMI, nullptr );
   pmIL->EmitCall( OpCodes::Call, convertInt32MI, nullptr );
   pmIL->Emit( OpCodes::Stloc, y2LB );
   pmIL->Emit( OpCodes::Ldloc, x1LB );
   pmIL->Emit( OpCodes::Ldloc, y1LB );
   pmIL->Emit( OpCodes::Newobj, pointCtor );
   pmIL->Emit( OpCodes::Stloc, point1LB );
   pmIL->Emit( OpCodes::Ldloc, x2LB );
   pmIL->Emit( OpCodes::Ldloc, y2LB );
   pmIL->Emit( OpCodes::Newobj, pointCtor );
   pmIL->Emit( OpCodes::Stloc, point2LB );
   pmIL->Emit( OpCodes::Ldstr, "( {0}, {1}) . ( {2}, {3}) = {4}." );
   pmIL->Emit( OpCodes::Ldc_I4_5 );
   pmIL->Emit( OpCodes::Newarr, Object::typeid );
   pmIL->Emit( OpCodes::Stloc, tempObjArrLB );
   pmIL->Emit( OpCodes::Ldloc, tempObjArrLB );
   pmIL->Emit( OpCodes::Ldc_I4_0 );
   pmIL->Emit( OpCodes::Ldloc, x1LB );
   pmIL->Emit( OpCodes::Box, int::typeid );
   pmIL->Emit( OpCodes::Stelem_Ref );
   pmIL->Emit( OpCodes::Ldloc, tempObjArrLB );
   pmIL->Emit( OpCodes::Ldc_I4_1 );
   pmIL->Emit( OpCodes::Ldloc, y1LB );
   pmIL->Emit( OpCodes::Box, int::typeid );
   pmIL->Emit( OpCodes::Stelem_Ref );
   pmIL->Emit( OpCodes::Ldloc, tempObjArrLB );
   pmIL->Emit( OpCodes::Ldc_I4_2 );
   pmIL->Emit( OpCodes::Ldloc, x2LB );
   pmIL->Emit( OpCodes::Box, int::typeid );
   pmIL->Emit( OpCodes::Stelem_Ref );
   pmIL->Emit( OpCodes::Ldloc, tempObjArrLB );
   pmIL->Emit( OpCodes::Ldc_I4_3 );
   pmIL->Emit( OpCodes::Ldloc, y2LB );
   pmIL->Emit( OpCodes::Box, int::typeid );
   pmIL->Emit( OpCodes::Stelem_Ref );
   pmIL->Emit( OpCodes::Ldloc, tempObjArrLB );
   pmIL->Emit( OpCodes::Ldc_I4_4 );
   pmIL->Emit( OpCodes::Ldloc, point1LB );
   pmIL->Emit( OpCodes::Ldloc, point2LB );
   pmIL->EmitCall( OpCodes::Callvirt, pointDPBldr, nullptr );
   pmIL->Emit( OpCodes::Box, int::typeid );
   pmIL->Emit( OpCodes::Stelem_Ref );
   pmIL->Emit( OpCodes::Ldloc, tempObjArrLB );
   pmIL->EmitCall( OpCodes::Call, writeLineMI, nullptr );
   pmIL->Emit( OpCodes::Ret );
   Console::WriteLine( "PointMain (entry point) built." );
   pointType = myTypeBldr->CreateType();
   Console::WriteLine( "Type completed." );
   myAsmBldr->SetEntryPoint( pointMainBldr );
   myAsmBldr->Save( asmFileName );
   Console::WriteLine( "Assembly saved as ' {0}'.", asmFileName );
   Console::WriteLine( "Type ' {0}' at the prompt to run your new dynamically generated dot product calculator.", asmFileName );
   
   // After execution, this program will have generated and written to disk,
   // in the directory you executed it from, a program named
   // <name_you_entered_here>.exe. You can run it by typing
   // the name you gave it during execution, in the same directory where
   // you executed this program.
   return pointType;
}

int main()
{
   Type^ myType = BuildDynAssembly();
   Console::WriteLine( "---" );
   
   // Let's invoke the type 'Point' created in our dynamic assembly.
   array<Object^>^temp3 = {nullptr,nullptr};
   Object^ ptInstance = Activator::CreateInstance( myType, temp3 );
   myType->InvokeMember( "PointMain", BindingFlags::InvokeMethod, nullptr, ptInstance, gcnew array<Object^>(0) );
}


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

// The Point class is the class we will reflect on and copy into our
// dynamic assembly. The public static function PointMain() will be used
// as our entry point.
//
// We are constructing the type seen here dynamically, and will write it
// out into a .exe file for later execution from the command-line.
// --- 
// class Point {
//   
//   private int x;
//   private int y;
//
//   public Point(int ix, int iy) {
//
//   	this.x = ix;
//    	this.y = iy;
//
//   }
//
//   public int DotProduct (Point p) {
//   
//   	return ((this.x * p.x) + (this.y * p.y));
//
//   }
//
//   public static void PointMain() {
//     
//     Console.Write("Enter the 'x' value for point 1: "); 
//     int x1 = Convert.ToInt32(Console.ReadLine());
//     
//     Console.Write("Enter the 'y' value for point 1: ");
//     int y1 = Convert.ToInt32(Console.ReadLine());
//
//     Console.Write("Enter the 'x' value for point 2: "); 
//     int x2 = Convert.ToInt32(Console.ReadLine());
//     
//     Console.Write("Enter the 'y' value for point 2: ");
//     int y2 = Convert.ToInt32(Console.ReadLine());
//
//     Point p1 = new Point(x1, y1);
//     Point p2 = new Point(x2, y2);
//
//     Console.WriteLine("({0}, {1}) . ({2}, {3}) = {4}.",
//		       x1, y1, x2, y2, p1.DotProduct(p2));
//   
//   }
//
// }
// ---

class AssemblyBuilderDemo {

   public static Type BuildDynAssembly() {

        Type pointType = null;

    	AppDomain currentDom = Thread.GetDomain();

	Console.Write("Please enter a name for your new assembly: ");
	StringBuilder asmFileNameBldr = new StringBuilder();
        asmFileNameBldr.Append(Console.ReadLine());
	asmFileNameBldr.Append(".exe");
	string asmFileName = asmFileNameBldr.ToString();	

        AssemblyName myAsmName = new AssemblyName();
	myAsmName.Name = "MyDynamicAssembly";

        AssemblyBuilder myAsmBldr = currentDom.DefineDynamicAssembly(
					       myAsmName,
					       AssemblyBuilderAccess.RunAndSave);

        // We've created a dynamic assembly space - now, we need to create a module
        // within it to reflect the type Point into.

	ModuleBuilder myModuleBldr = myAsmBldr.DefineDynamicModule(asmFileName,
							           asmFileName);
      
	TypeBuilder myTypeBldr =  myModuleBldr.DefineType("Point");
    
        FieldBuilder xField = myTypeBldr.DefineField("x", typeof(int),
                                                     FieldAttributes.Private);
        FieldBuilder yField = myTypeBldr.DefineField("y", typeof(int), 
                                                     FieldAttributes.Private); 

        // Build the constructor.

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

        Type[] ctorParams = new Type[] {typeof(int), typeof(int)};
        ConstructorBuilder pointCtor = myTypeBldr.DefineConstructor(
 				                  MethodAttributes.Public,
				                  CallingConventions.Standard,
				                  ctorParams);
        ILGenerator ctorIL = pointCtor.GetILGenerator();
        ctorIL.Emit(OpCodes.Ldarg_0);
        ctorIL.Emit(OpCodes.Call, objCtor);
        ctorIL.Emit(OpCodes.Ldarg_0);
        ctorIL.Emit(OpCodes.Ldarg_1);
        ctorIL.Emit(OpCodes.Stfld, xField); 
        ctorIL.Emit(OpCodes.Ldarg_0);
        ctorIL.Emit(OpCodes.Ldarg_2);
        ctorIL.Emit(OpCodes.Stfld, yField); 
        ctorIL.Emit(OpCodes.Ret);

	// Build the DotProduct method.

        Console.WriteLine("Constructor built.");

	MethodBuilder pointDPBldr = myTypeBldr.DefineMethod("DotProduct",
							    MethodAttributes.Public,
							    typeof(int),
							    new Type[] {myTypeBldr});
							   
	ILGenerator dpIL = pointDPBldr.GetILGenerator();
	dpIL.Emit(OpCodes.Ldarg_0);
	dpIL.Emit(OpCodes.Ldfld, xField);
	dpIL.Emit(OpCodes.Ldarg_1);
	dpIL.Emit(OpCodes.Ldfld, xField);
	dpIL.Emit(OpCodes.Mul_Ovf_Un);
	dpIL.Emit(OpCodes.Ldarg_0);
	dpIL.Emit(OpCodes.Ldfld, yField);
	dpIL.Emit(OpCodes.Ldarg_1);
	dpIL.Emit(OpCodes.Ldfld, yField);
	dpIL.Emit(OpCodes.Mul_Ovf_Un);
	dpIL.Emit(OpCodes.Add_Ovf_Un);
	dpIL.Emit(OpCodes.Ret);

  	// Build the PointMain method.

        Console.WriteLine("DotProduct built.");

	MethodBuilder pointMainBldr = myTypeBldr.DefineMethod("PointMain",
							    MethodAttributes.Public |
							    MethodAttributes.Static,
							    typeof(void),
							    null);
        pointMainBldr.InitLocals = true;
	ILGenerator pmIL = pointMainBldr.GetILGenerator();

	// We have four methods that we wish to call, and must represent as
	// MethodInfo tokens:
	// - void Console.WriteLine(string)
	// - string Console.ReadLine()
	// - int Convert.Int32(string)
	// - void Console.WriteLine(string, object[])

	MethodInfo writeMI = typeof(Console).GetMethod(
					     "Write",
					     new Type[] {typeof(string)});
	MethodInfo readLineMI = typeof(Console).GetMethod(
					        "ReadLine",
					        new Type[0]);
	MethodInfo convertInt32MI = typeof(Convert).GetMethod(
						    "ToInt32",
					            new Type[] {typeof(string)});
	Type[] wlParams = new Type[] {typeof(string), typeof(object[])};
	MethodInfo writeLineMI = typeof(Console).GetMethod(
						 "WriteLine",
						 wlParams);

	// Although we could just refer to the local variables by
	// index (short ints for Ldloc/Stloc, bytes for LdLoc_S/Stloc_S),
	// this time, we'll use LocalBuilders for clarity and to
	// demonstrate their usage and syntax.

	LocalBuilder x1LB = pmIL.DeclareLocal(typeof(int));				
	LocalBuilder y1LB = pmIL.DeclareLocal(typeof(int));				
	LocalBuilder x2LB = pmIL.DeclareLocal(typeof(int));				
	LocalBuilder y2LB = pmIL.DeclareLocal(typeof(int));				
	LocalBuilder point1LB = pmIL.DeclareLocal(myTypeBldr);				
	LocalBuilder point2LB = pmIL.DeclareLocal(myTypeBldr);				
	LocalBuilder tempObjArrLB = pmIL.DeclareLocal(typeof(object[]));				

	pmIL.Emit(OpCodes.Ldstr, "Enter the 'x' value for point 1: ");	
	pmIL.EmitCall(OpCodes.Call, writeMI, null);
	pmIL.EmitCall(OpCodes.Call, readLineMI, null);
	pmIL.EmitCall(OpCodes.Call, convertInt32MI, null);
	pmIL.Emit(OpCodes.Stloc, x1LB);

	pmIL.Emit(OpCodes.Ldstr, "Enter the 'y' value for point 1: ");	
	pmIL.EmitCall(OpCodes.Call, writeMI, null);
	pmIL.EmitCall(OpCodes.Call, readLineMI, null);
	pmIL.EmitCall(OpCodes.Call, convertInt32MI, null);
	pmIL.Emit(OpCodes.Stloc, y1LB);

	pmIL.Emit(OpCodes.Ldstr, "Enter the 'x' value for point 2: ");	
	pmIL.EmitCall(OpCodes.Call, writeMI, null);
	pmIL.EmitCall(OpCodes.Call, readLineMI, null);
	pmIL.EmitCall(OpCodes.Call, convertInt32MI, null);
	pmIL.Emit(OpCodes.Stloc, x2LB);

	pmIL.Emit(OpCodes.Ldstr, "Enter the 'y' value for point 2: ");	
	pmIL.EmitCall(OpCodes.Call, writeMI, null);
	pmIL.EmitCall(OpCodes.Call, readLineMI, null);
	pmIL.EmitCall(OpCodes.Call, convertInt32MI, null);
	pmIL.Emit(OpCodes.Stloc, y2LB);

	pmIL.Emit(OpCodes.Ldloc, x1LB);
	pmIL.Emit(OpCodes.Ldloc, y1LB);
	pmIL.Emit(OpCodes.Newobj, pointCtor);
	pmIL.Emit(OpCodes.Stloc, point1LB);

	pmIL.Emit(OpCodes.Ldloc, x2LB);
	pmIL.Emit(OpCodes.Ldloc, y2LB);
	pmIL.Emit(OpCodes.Newobj, pointCtor);
	pmIL.Emit(OpCodes.Stloc, point2LB);

	pmIL.Emit(OpCodes.Ldstr, "({0}, {1}) . ({2}, {3}) = {4}.");
	pmIL.Emit(OpCodes.Ldc_I4_5);
	pmIL.Emit(OpCodes.Newarr, typeof(Object));
	pmIL.Emit(OpCodes.Stloc, tempObjArrLB);

	pmIL.Emit(OpCodes.Ldloc, tempObjArrLB);
	pmIL.Emit(OpCodes.Ldc_I4_0);
	pmIL.Emit(OpCodes.Ldloc, x1LB);
	pmIL.Emit(OpCodes.Box, typeof(int));
	pmIL.Emit(OpCodes.Stelem_Ref);

	pmIL.Emit(OpCodes.Ldloc, tempObjArrLB);
	pmIL.Emit(OpCodes.Ldc_I4_1);
	pmIL.Emit(OpCodes.Ldloc, y1LB);
	pmIL.Emit(OpCodes.Box, typeof(int));
	pmIL.Emit(OpCodes.Stelem_Ref);

	pmIL.Emit(OpCodes.Ldloc, tempObjArrLB);
	pmIL.Emit(OpCodes.Ldc_I4_2);
	pmIL.Emit(OpCodes.Ldloc, x2LB);
	pmIL.Emit(OpCodes.Box, typeof(int));
	pmIL.Emit(OpCodes.Stelem_Ref);

	pmIL.Emit(OpCodes.Ldloc, tempObjArrLB);
	pmIL.Emit(OpCodes.Ldc_I4_3);
	pmIL.Emit(OpCodes.Ldloc, y2LB);
	pmIL.Emit(OpCodes.Box, typeof(int));
	pmIL.Emit(OpCodes.Stelem_Ref);

	pmIL.Emit(OpCodes.Ldloc, tempObjArrLB);
	pmIL.Emit(OpCodes.Ldc_I4_4);
	pmIL.Emit(OpCodes.Ldloc, point1LB);
	pmIL.Emit(OpCodes.Ldloc, point2LB);
	pmIL.EmitCall(OpCodes.Callvirt, pointDPBldr, null);

	pmIL.Emit(OpCodes.Box, typeof(int));
	pmIL.Emit(OpCodes.Stelem_Ref);
	pmIL.Emit(OpCodes.Ldloc, tempObjArrLB);
	pmIL.EmitCall(OpCodes.Call, writeLineMI, null);

	pmIL.Emit(OpCodes.Ret);

        Console.WriteLine("PointMain (entry point) built.");

        pointType = myTypeBldr.CreateType();

        Console.WriteLine("Type completed.");

	myAsmBldr.SetEntryPoint(pointMainBldr);

        myAsmBldr.Save(asmFileName);

        Console.WriteLine("Assembly saved as '{0}'.", asmFileName);
        Console.WriteLine("Type '{0}' at the prompt to run your new " +
		          "dynamically generated dot product calculator.",
			   asmFileName);

	// After execution, this program will have generated and written to disk,
        // in the directory you executed it from, a program named 
	// <name_you_entered_here>.exe. You can run it by typing
	// the name you gave it during execution, in the same directory where
	// you executed this program.

	return pointType;
   
   }

   public static void Main() {

     Type myType = BuildDynAssembly(); 
     Console.WriteLine("---");

     // Let's invoke the type 'Point' created in our dynamic assembly. 
   
     object ptInstance = Activator.CreateInstance(myType, new object[] {0,0}); 
						  
     myType.InvokeMember("PointMain",
			  BindingFlags.InvokeMethod,
			  null,
			  ptInstance,
			  new object[0]); 

            
   }
}



Imports System
Imports System.Text
Imports System.Threading
Imports System.Reflection
Imports System.Reflection.Emit

 _

' The Point class is the class we will reflect on and copy into our
' dynamic assembly. The public static function PointMain() will be used
' as our entry point.
'
' We are constructing the type seen here dynamically, and will write it
' out into a .exe file for later execution from the command-line.
' --- 
' Class Point
'    
'    Private x As Integer
'    Private y As Integer
'    
'    
'    Public Sub New(ix As Integer, iy As Integer)
'       
'       Me.x = ix
'       Me.y = iy
'    End Sub 'New
'     
'    
'    Public Function DotProduct(p As Point) As Integer
'       
'       Return Me.x * p.x + Me.y * p.y
'    End Function 'DotProduct
'     
'    
'    Public Shared Sub Main()
'       
'       Console.Write("Enter the 'x' value for point 1: ")
'       Dim x1 As Integer = Convert.ToInt32(Console.ReadLine())
'       
'       Console.Write("Enter the 'y' value for point 1: ")
'       Dim y1 As Integer = Convert.ToInt32(Console.ReadLine())
'       
'       Console.Write("Enter the 'x' value for point 2: ")
'       Dim x2 As Integer = Convert.ToInt32(Console.ReadLine())
'       
'       Console.Write("Enter the 'y' value for point 2: ")
'       Dim y2 As Integer = Convert.ToInt32(Console.ReadLine())
'       
'       Dim p1 As New Point(x1, y1)
'       Dim p2 As New Point(x2, y2)
'       
'       Console.WriteLine("({0}, {1}) . ({2}, {3}) = {4}.", x1, y1, x2, y2, p1.DotProduct(p2))
'    End Sub 'Main
' End Class 'Point 
' ---
Class AssemblyBuilderDemo
   
   
   Public Shared Function BuildDynAssembly() As Type
      
      Dim pointType As Type = Nothing
      
      Dim currentDom As AppDomain = Thread.GetDomain()
      
      Console.Write("Please enter a name for your new assembly: ")
      Dim asmFileNameBldr As New StringBuilder()
      asmFileNameBldr.Append(Console.ReadLine())
      asmFileNameBldr.Append(".exe")
      Dim asmFileName As String = asmFileNameBldr.ToString()
      
      Dim myAsmName As New AssemblyName()
      myAsmName.Name = "MyDynamicAssembly"
      
      Dim myAsmBldr As AssemblyBuilder = currentDom.DefineDynamicAssembly(myAsmName, _
					 AssemblyBuilderAccess.RunAndSave)
      
      ' We've created a dynamic assembly space - now, we need to create a module
      ' within it to reflect the type Point into.
      Dim myModuleBldr As ModuleBuilder = myAsmBldr.DefineDynamicModule(asmFileName, _
									asmFileName)
      
      Dim myTypeBldr As TypeBuilder = myModuleBldr.DefineType("Point")
      
      Dim xField As FieldBuilder = myTypeBldr.DefineField("x", GetType(Integer), _
						          FieldAttributes.Private)
      Dim yField As FieldBuilder = myTypeBldr.DefineField("y", GetType(Integer), _
					 		  FieldAttributes.Private)
      
      ' Build the constructor.
      Dim objType As Type = Type.GetType("System.Object")
      Dim objCtor As ConstructorInfo = objType.GetConstructor(New Type() {})
      
      Dim ctorParams() As Type = {GetType(Integer), GetType(Integer)}
      Dim pointCtor As ConstructorBuilder = myTypeBldr.DefineConstructor( _
					    MethodAttributes.Public, _
					    CallingConventions.Standard, _
					    ctorParams)
      Dim ctorIL As ILGenerator = pointCtor.GetILGenerator()
      ctorIL.Emit(OpCodes.Ldarg_0)
      ctorIL.Emit(OpCodes.Call, objCtor)
      ctorIL.Emit(OpCodes.Ldarg_0)
      ctorIL.Emit(OpCodes.Ldarg_1)
      ctorIL.Emit(OpCodes.Stfld, xField)
      ctorIL.Emit(OpCodes.Ldarg_0)
      ctorIL.Emit(OpCodes.Ldarg_2)
      ctorIL.Emit(OpCodes.Stfld, yField)
      ctorIL.Emit(OpCodes.Ret)
      
      ' Build the DotProduct method.
      Console.WriteLine("Constructor built.")
      
      Dim pointDPBldr As MethodBuilder = myTypeBldr.DefineMethod("DotProduct", _
								 MethodAttributes.Public, _
								 GetType(Integer), _
								 New Type(0) {myTypeBldr})
      
      Dim dpIL As ILGenerator = pointDPBldr.GetILGenerator()
      dpIL.Emit(OpCodes.Ldarg_0)
      dpIL.Emit(OpCodes.Ldfld, xField)
      dpIL.Emit(OpCodes.Ldarg_1)
      dpIL.Emit(OpCodes.Ldfld, xField)
      dpIL.Emit(OpCodes.Mul_Ovf_Un)
      dpIL.Emit(OpCodes.Ldarg_0)
      dpIL.Emit(OpCodes.Ldfld, yField)
      dpIL.Emit(OpCodes.Ldarg_1)
      dpIL.Emit(OpCodes.Ldfld, yField)
      dpIL.Emit(OpCodes.Mul_Ovf_Un)
      dpIL.Emit(OpCodes.Add_Ovf_Un)
      dpIL.Emit(OpCodes.Ret)
      
      ' Build the PointMain method.
      Console.WriteLine("DotProduct built.")
      
      Dim pointMainBldr As MethodBuilder = myTypeBldr.DefineMethod("PointMain", _
						      MethodAttributes.Public Or _
						      MethodAttributes.Static, _
						      Nothing, Nothing)
      pointMainBldr.InitLocals = True
      Dim pmIL As ILGenerator = pointMainBldr.GetILGenerator()
      
      ' We have four methods that we wish to call, and must represent as
      ' MethodInfo tokens:
      ' - Sub Console.WriteLine(string)
      ' - Function Console.ReadLine() As String
      ' - Function Convert.Int32(string) As Int
      ' - Sub Console.WriteLine(string, object[])

      Dim writeMI As MethodInfo = GetType(Console).GetMethod("Write", _
					           New Type(0) {GetType(String)}) 
								     
      Dim readLineMI As MethodInfo = GetType(Console).GetMethod("ReadLine", _
						      New Type() {})
      Dim convertInt32MI As MethodInfo = GetType(Convert).GetMethod("ToInt32", _
							  New Type(0) {GetType(String)})
      Dim wlParams() As Type = {GetType(String), GetType(Object())}
      Dim writeLineMI As MethodInfo = GetType(Console).GetMethod("WriteLine", wlParams)
      
      ' Although we could just refer to the local variables by
      ' index (short ints for Ldloc/Stloc, bytes for LdLoc_S/Stloc_S),
      ' this time, we'll use LocalBuilders for clarity and to
      ' demonstrate their usage and syntax.

      Dim x1LB As LocalBuilder = pmIL.DeclareLocal(GetType(Integer))
      Dim y1LB As LocalBuilder = pmIL.DeclareLocal(GetType(Integer))
      Dim x2LB As LocalBuilder = pmIL.DeclareLocal(GetType(Integer))
      Dim y2LB As LocalBuilder = pmIL.DeclareLocal(GetType(Integer))
      Dim point1LB As LocalBuilder = pmIL.DeclareLocal(myTypeBldr)
      Dim point2LB As LocalBuilder = pmIL.DeclareLocal(myTypeBldr)
      Dim tempObjArrLB As LocalBuilder = pmIL.DeclareLocal(GetType(Object()))
      
      pmIL.Emit(OpCodes.Ldstr, "Enter the 'x' value for point 1: ")
      pmIL.EmitCall(OpCodes.Call, writeMI, Nothing)
      pmIL.EmitCall(OpCodes.Call, readLineMI, Nothing)
      pmIL.EmitCall(OpCodes.Call, convertInt32MI, Nothing)
      pmIL.Emit(OpCodes.Stloc, x1LB)
      
      pmIL.Emit(OpCodes.Ldstr, "Enter the 'y' value for point 1: ")
      pmIL.EmitCall(OpCodes.Call, writeMI, Nothing)
      pmIL.EmitCall(OpCodes.Call, readLineMI, Nothing)
      pmIL.EmitCall(OpCodes.Call, convertInt32MI, Nothing)
      pmIL.Emit(OpCodes.Stloc, y1LB)
      
      pmIL.Emit(OpCodes.Ldstr, "Enter the 'x' value for point 2: ")
      pmIL.EmitCall(OpCodes.Call, writeMI, Nothing)
      pmIL.EmitCall(OpCodes.Call, readLineMI, Nothing)
      pmIL.EmitCall(OpCodes.Call, convertInt32MI, Nothing)
      pmIL.Emit(OpCodes.Stloc, x2LB)
      
      pmIL.Emit(OpCodes.Ldstr, "Enter the 'y' value for point 2: ")
      pmIL.EmitCall(OpCodes.Call, writeMI, Nothing)
      pmIL.EmitCall(OpCodes.Call, readLineMI, Nothing)
      pmIL.EmitCall(OpCodes.Call, convertInt32MI, Nothing)
      pmIL.Emit(OpCodes.Stloc, y2LB)
      
      pmIL.Emit(OpCodes.Ldloc, x1LB)
      pmIL.Emit(OpCodes.Ldloc, y1LB)
      pmIL.Emit(OpCodes.Newobj, pointCtor)
      pmIL.Emit(OpCodes.Stloc, point1LB)
      
      pmIL.Emit(OpCodes.Ldloc, x2LB)
      pmIL.Emit(OpCodes.Ldloc, y2LB)
      pmIL.Emit(OpCodes.Newobj, pointCtor)
      pmIL.Emit(OpCodes.Stloc, point2LB)
      
      pmIL.Emit(OpCodes.Ldstr, "({0}, {1}) . ({2}, {3}) = {4}.")
      pmIL.Emit(OpCodes.Ldc_I4_5)
      pmIL.Emit(OpCodes.Newarr, GetType([Object]))
      pmIL.Emit(OpCodes.Stloc, tempObjArrLB)
      
      pmIL.Emit(OpCodes.Ldloc, tempObjArrLB)
      pmIL.Emit(OpCodes.Ldc_I4_0)
      pmIL.Emit(OpCodes.Ldloc, x1LB)
      pmIL.Emit(OpCodes.Box, GetType(Integer))
      pmIL.Emit(OpCodes.Stelem_Ref)
      
      pmIL.Emit(OpCodes.Ldloc, tempObjArrLB)
      pmIL.Emit(OpCodes.Ldc_I4_1)
      pmIL.Emit(OpCodes.Ldloc, y1LB)
      pmIL.Emit(OpCodes.Box, GetType(Integer))
      pmIL.Emit(OpCodes.Stelem_Ref)
      
      pmIL.Emit(OpCodes.Ldloc, tempObjArrLB)
      pmIL.Emit(OpCodes.Ldc_I4_2)
      pmIL.Emit(OpCodes.Ldloc, x2LB)
      pmIL.Emit(OpCodes.Box, GetType(Integer))
      pmIL.Emit(OpCodes.Stelem_Ref)
      
      pmIL.Emit(OpCodes.Ldloc, tempObjArrLB)
      pmIL.Emit(OpCodes.Ldc_I4_3)
      pmIL.Emit(OpCodes.Ldloc, y2LB)
      pmIL.Emit(OpCodes.Box, GetType(Integer))
      pmIL.Emit(OpCodes.Stelem_Ref)
      
      pmIL.Emit(OpCodes.Ldloc, tempObjArrLB)
      pmIL.Emit(OpCodes.Ldc_I4_4)
      pmIL.Emit(OpCodes.Ldloc, point1LB)
      pmIL.Emit(OpCodes.Ldloc, point2LB)
      pmIL.EmitCall(OpCodes.Callvirt, pointDPBldr, Nothing)
      
      pmIL.Emit(OpCodes.Box, GetType(Integer))
      pmIL.Emit(OpCodes.Stelem_Ref)
      pmIL.Emit(OpCodes.Ldloc, tempObjArrLB)
      pmIL.EmitCall(OpCodes.Call, writeLineMI, Nothing)
      
      pmIL.Emit(OpCodes.Ret)
      
      Console.WriteLine("PointMain (entry point) built.")
      
      pointType = myTypeBldr.CreateType()
      
      Console.WriteLine("Type completed.")
      
      myAsmBldr.SetEntryPoint(pointMainBldr)
      
      myAsmBldr.Save(asmFileName)
      
      Console.WriteLine("Assembly saved as '{0}'.", asmFileName)
      Console.WriteLine("Type '{0}' at the prompt to run your new " + "dynamically generated dot product calculator.", asmFileName)
      
      ' After execution, this program will have generated and written to disk,
      ' in the directory you executed it from, a program named 
      ' <name_you_entered_here>.exe. You can run it by typing
      ' the name you gave it during execution, in the same directory where
      ' you executed this program.

      Return pointType

   End Function 'BuildDynAssembly
    
   
   Public Shared Sub Main()
      
      Dim myType As Type = BuildDynAssembly()
      Console.WriteLine("---")
      
      ' Let's invoke the type 'Point' created in our dynamic assembly. 
      Dim ptInstance As Object = Activator.CreateInstance(myType, New Object(1) {0, 0})
      
      myType.InvokeMember("PointMain", BindingFlags.InvokeMethod, _
			  Nothing, ptInstance, New Object() {})

   End Sub 'Main

End Class 'AssemblyBuilderDemo





Comentarios

Este método guarda todos los módulos dinámicos no transitorios definidos en este ensamblado dinámico.This method saves all non-transient dynamic modules defined in this dynamic assembly. No se guardan los módulos dinámicos transitorios.Transient dynamic modules are not saved. El nombre de archivo de ensamblado puede ser el mismo que el nombre de uno de los módulos.The assembly file name can be the same as the name of one of the modules. Si es así, el manifiesto del ensamblado se almacena dentro de ese módulo.If so, the assembly manifest is stored within that module. assemblyFileName puede ser diferente de los nombres de todos los módulos incluidos en el ensamblado.assemblyFileName can be different from the names of all of the modules contained within the assembly. Si es así, el archivo de ensamblado contiene sólo el manifiesto del ensamblado.If so, the assembly file contains only the assembly manifest.

Para cada ResourceWriter obtenidos mediante DefineResource, este método escribe el archivo .resources y llama Close para cerrar la secuencia.For each ResourceWriter obtained using DefineResource, this method writes the .resources file and calls Close to close the stream.

El assemblyFileName debe ser un nombre de archivo simple sin un componente de unidad o el directorio.The assemblyFileName needs to be a simple file name without a drive or directory component. Para crear un ensamblado en un directorio específico, use uno de los DefineDynamicAssembly métodos que toma un argumento de directorio de destino.To create an assembly in a specific directory, use one of the DefineDynamicAssembly methods that takes a target directory argument.

En .NET Framework versión 2.0, esta sobrecarga de la Save es equivalente a llamar al método el Save(String, PortableExecutableKinds, ImageFileMachine) sobrecarga del método con ILOnly para el portableExecutableKind parámetro y I386 para el imageFileMachine parámetro.In the .NET Framework version 2.0, this overload of the Save method is equivalent to calling the Save(String, PortableExecutableKinds, ImageFileMachine) method overload with ILOnly for the portableExecutableKind parameter and I386 for the imageFileMachine parameter.

Seguridad

FileIOPermission
Escribir = true o Append = true se necesita para guardar este ensamblado en el nombre de archivo especificado.Write = true or Append = true is needed to save this assembly to the specified file name.

ReflectionPermission
Cuando se invoca en tiempo de ejecución a través de mecanismos como InvokeMember(String, BindingFlags, Binder, Object, Object[], ParameterModifier[], CultureInfo, String[]).when invoked late-bound through mechanisms such as InvokeMember(String, BindingFlags, Binder, Object, Object[], ParameterModifier[], CultureInfo, String[]). Enumeración asociada: MemberAccess.Associated enumeration: MemberAccess.

Save(String, PortableExecutableKinds, ImageFileMachine) Save(String, PortableExecutableKinds, ImageFileMachine) Save(String, PortableExecutableKinds, ImageFileMachine)

Guarda este ensamblado dinámico en disco, especificando la naturaleza del código en los ejecutables del ensamblado y la plataforma de destino.Saves this dynamic assembly to disk, specifying the nature of code in the assembly's executables and the target platform.

public:
 void Save(System::String ^ assemblyFileName, System::Reflection::PortableExecutableKinds portableExecutableKind, System::Reflection::ImageFileMachine imageFileMachine);
public void Save (string assemblyFileName, System.Reflection.PortableExecutableKinds portableExecutableKind, System.Reflection.ImageFileMachine imageFileMachine);
member this.Save : string * System.Reflection.PortableExecutableKinds * System.Reflection.ImageFileMachine -> unit

Parámetros

assemblyFileName
String String String String

El nombre de archivo del ensamblado.The file name of the assembly.

portableExecutableKind
PortableExecutableKinds PortableExecutableKinds PortableExecutableKinds PortableExecutableKinds

Combinación bit a bit de los valores de PortableExecutableKinds que especifica la naturaleza del código.A bitwise combination of the PortableExecutableKinds values that specifies the nature of the code.

imageFileMachine
ImageFileMachine ImageFileMachine ImageFileMachine ImageFileMachine

Uno de los valores de ImageFileMachine que especifica la plataforma de destino.One of the ImageFileMachine values that specifies the target platform.

Excepciones

La longitud de assemblyFileName es 0.The length of assemblyFileName is 0.

O bien-or- Hay dos o más archivos de recursos de módulos en el ensamblado con el mismo nombre.There are two or more modules resource files in the assembly with the same name.

O bien-or- El directorio de destino del ensamblado no es válido.The target directory of the assembly is invalid.

O bien-or- assemblyFileName no es un nombre de archivo simple (por ejemplo, tiene un componente de directorio o de unidad), o se ha definido más de un recurso no administrado, incluido un recurso de información de versión, en este ensamblado.assemblyFileName is not a simple file name (for example, has a directory or drive component), or more than one unmanaged resource, including a version information resources, was defined in this assembly.

O bien-or- La cadena CultureInfo de AssemblyCultureAttribute no es válida y se ha llamado a DefineVersionInfoResource(String, String, String, String, String) antes de llamar a este método.The CultureInfo string in AssemblyCultureAttribute is not a valid string and DefineVersionInfoResource(String, String, String, String, String) was called prior to calling this method.

assemblyFileName es null.assemblyFileName is null.

Este ensamblado se ha guardado anteriormente.This assembly has been saved before.

O bien-or- Este ensamblado tiene acceso RunAssemblyBuilderAccessThis assembly has access RunAssemblyBuilderAccess

Se produce un error de salida al guardar.An output error occurs during the save.

No se ha llamado a CreateType() para ninguno de los tipos de los módulos del ensamblado que se van a escribir en disco.CreateType() has not been called for any of the types in the modules of the assembly to be written to disk.

Comentarios

Si imageFileMachine y portableExecutableKind son incompatibles, imageFileMachine tiene prioridad sobre portableExecutableKind.If imageFileMachine and portableExecutableKind are incompatible, imageFileMachine takes precedence over portableExecutableKind. No se inicia ninguna excepción.No exception is thrown. Por ejemplo, si especifica ImageFileMachine.I386 con PortableExecutableKinds.PE32Plus, PortableExecutableKinds.PE32Plus se omite.For example, if you specify ImageFileMachine.I386 with PortableExecutableKinds.PE32Plus, PortableExecutableKinds.PE32Plus is ignored.

Este método guarda todos los módulos dinámicos no transitorios definidos en este ensamblado dinámico.This method saves all non-transient dynamic modules defined in this dynamic assembly. No se guardan los módulos dinámicos transitorios.Transient dynamic modules are not saved. El nombre de archivo de ensamblado puede ser el mismo que el nombre de uno de los módulos.The assembly file name can be the same as the name of one of the module. Si es así, el manifiesto del ensamblado se almacena dentro de ese módulo.If so, the assembly manifest is stored within that module. assemblyFileName puede ser diferente de los nombres de todos los módulos incluidos en el ensamblado.assemblyFileName can be different from the names of all of the modules contained within the assembly. Si es así, el archivo de ensamblado contiene sólo el manifiesto del ensamblado.If so, the assembly file contains only the assembly manifest.

Para cada ResourceWriter obtenidos mediante DefineResource, este método escribe el archivo .resources y llama Close para cerrar la secuencia.For each ResourceWriter obtained using DefineResource, this method writes the .resources file and calls Close to close the stream.

El assemblyFileName debe ser un nombre de archivo simple sin un componente de unidad o el directorio.The assemblyFileName needs to be a simple file name without a drive or directory component. Para crear un ensamblado en un directorio específico, use uno de los DefineDynamicAssembly métodos que toma un argumento de directorio de destino.To create an assembly in a specific directory, use one of the DefineDynamicAssembly methods that takes a target directory argument.

Seguridad

FileIOPermission
Escribir = true o Append = true se necesita para guardar este ensamblado en el nombre de archivo especificado.Write = true or Append = true is needed to save this assembly to the specified file name.

ReflectionPermission
Cuando se invoca en tiempo de ejecución a través de mecanismos como InvokeMember(String, BindingFlags, Binder, Object, Object[], ParameterModifier[], CultureInfo, String[]).when invoked late-bound through mechanisms such as InvokeMember(String, BindingFlags, Binder, Object, Object[], ParameterModifier[], CultureInfo, String[]). Enumeración asociada: MemberAccess.Associated enumeration: MemberAccess.

Se aplica a