This documentation is archived and is not being maintained.

DynamicMethod Constructor (String, Type, Type[])

Initializes an anonymously hosted dynamic method, specifying the method name, return type, and parameter types.

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

public DynamicMethod(
	string name,
	Type returnType,
	Type[] parameterTypes
)

Parameters

name
Type: System.String

The name of the dynamic method. This can be a zero-length string, but it cannot be null.

returnType
Type: System.Type

A Type object that specifies the return type of the dynamic method, or null if the method has no return type.

parameterTypes
Type: System.Type[]

An array of Type objects specifying the types of the parameters of the dynamic method, or null if the method has no parameters.

ExceptionCondition
ArgumentException

An element of parameterTypes is null or Void.

ArgumentNullException

name is null.

NotSupportedException

returnType is a type for which Type.IsByRef returns true.

The dynamic method that is created by this constructor is associated with an anonymous assembly instead of an existing type or module. The anonymous assembly exists only to provide a sandbox environment for dynamic methods, that is, to isolate them from other code. This environment makes it safe for the dynamic method to be emitted and executed by partially trusted code.

This constructor specifies that just-in-time (JIT) visibility checks will be enforced for the Microsoft intermediate language (MSIL) of the dynamic method. That is, the code in the dynamic method has access to public methods of public classes. Exceptions are thrown if the method tries to access types or members that are private, protected, or internal (Friend in Visual Basic). To create a dynamic method that has restricted ability to skip JIT visibility checks, use the DynamicMethod(String, Type, Type[], Boolean) constructor.

When an anonymously hosted dynamic method is constructed, the call stack of the emitting assembly is included. When the method is invoked, the permissions of the emitting assembly are used instead of the permissions of the actual caller. Thus, the dynamic method cannot execute at a higher level of privilege than that of the assembly that emitted it, even if it is passed to and executed by an assembly that has a higher trust level.

This constructor specifies the method attributes MethodAttributes.Public and MethodAttributes.Static, and the calling convention CallingConventions.Standard.

NoteNote:

This constructor was introduced in the .NET Framework version 3.5. For more information, see .NET Framework 3.5 Architecture.

The following code example demonstrates the use of dynamic methods with partially trusted code. It shows that the dynamic method can be emitted and executed, but that other security permissions are still required and can cause the dynamic method to throw a security exception.

The example defines a Worker class that can be marshaled across application domain boundaries. The class has a TestDynamicMethod method, which emits and executes a dynamic method. TestDynamicMethod optionally calls the Directory.GetCurrentDirectory method, which requires FileIOPermission.

The example creates an application domain that is partially trusted, creates an instance of the Worker class in the application domain, and executes the TestDynamicMethod method two times.

  • The first time the TestDynamicMethod method executes, it emits and executes a dynamic method that does not call any methods that require special permissions. Therefore, these operations are successful.

  • The second time the TestDynamicMethod method executes, it emits a dynamic method that calls the GetCurrentDirectory method. The dynamic method is successfully emitted and successfully executes until it calls GetCurrentDirectory. At that point, SecurityException is thrown, because the partially trusted application domain does not have permission to execute IO operations.

NoteNote:

If you build this code example in Visual Studio, you must change the name of the class to include the default namespace, which is the name of the project. For example, if the project is "AnonymouslyHosted", the class name must be "AnonymouslyHosted.Worker".

using System;
using System.Reflection.Emit;
using System.Reflection;
using System.Security;
using System.Security.Policy;
using System.IO;

// This code example works properly only if run from a fully trusted  
// location, such as your local computer. 
// 
public class Example
{
    static void Main()
    {
        // Get the display name of the executing assembly, to use when 
        // creating objects to run code in application domains.
        String asmName = Assembly.GetExecutingAssembly().FullName;

        // Create evidence for a partially trusted location, and use that 
        // evidence to create an application domain that is partially  
        // trusted.
        Object[] zoneEvidence = { new Zone(SecurityZone.Intranet) };
        Evidence partialTrust = new Evidence(zoneEvidence, zoneEvidence);
        AppDomain ad = AppDomain.CreateDomain("ChildDomain", partialTrust);

        // Create an instance of the Worker class in the partially trusted  
        // domain. Note: If you build this code example in Visual Studio,  
        // you must change the name of the class to include the default  
        // namespace, which is the project name. For example, if the project 
        // is "AnonymouslyHosted", the class is "AnonymouslyHosted.Worker".
        Worker w = (Worker) ad.CreateInstanceAndUnwrap(asmName, "Worker");

        // Emit and test a dynamic method that does not require any special  
        // permissions. Even though it is called from a partially trusted  
        // location, TestDynamicMethod successfully emits the dynamic method  
        // and executes it.
        w.TestDynamicMethod(false);

        // Emit and test a dynamic method that requires FileIOPermission. 
        // TestDynamicMethod successfully emits the dynamic method and calls 
        // it, but when the dynamic method calls GetCurrentDirectory, which 
        // requires FileIOPermission, an exception is thrown.
        w.TestDynamicMethod(true);
    }
}

public delegate int Test(String msg, int ret);

// The Worker class must inherit MarshalByRefObject so that its public  
// methods can be invoked across application domain boundaries. 
// 
public class Worker : MarshalByRefObject
{
    public void TestDynamicMethod(bool requiresPermissions)
    {
        // Emit the dynamic method. Since this dynamic method uses only  
        // public types and methods, no special permissions are required. 
        // Partially trusted code can perform this action.
        Test testMeth = GenerateTestMethod(requiresPermissions);

        // Use the delegate to execute the dynamic method. This action 
        // fails if (1) requiresPermissions is true, so that the dynamic 
        // method calls Directory.GetCurrentDirectory, and (2) the delegate 
        // is invoked from partially trusted code. If requirePermissions is 
        // false, the delegate can be invoked safely by partially trusted 
        // code. 
        try
        {
            int retval = testMeth("\nHello, World!", 42);
            Console.WriteLine( 
                "Executing delegate testMeth(\"Hello, World!\", 42) returned: {0}",
                retval);
        }
        catch (Exception ex)
        {
            Console.WriteLine("Executing the delegate caused a {0}:\n{1}",
                ex.GetType().Name, ex.Message);
        }
    }

    // GenerateTestMethod emits the dynamic method and returns a  
    // delegate of type Test that can be used to invoke the dynamic  
    // method. GenerateTestMethod reflects over public types and members, 
    // so it can be called by partially trusted code. However, if 
    // requiresPermissions is true, then the resulting dynamic method 
    // calls a function that requires FileIOPermission, which partially 
    // trusted code does not have unless it has been explicitly 
    // granted. 
    private Test GenerateTestMethod(bool requiresPermissions)
    {
        // Create an array that specifies the types of the parameters 
        // of the dynamic method. 
        Type[] paramTypes = { typeof(String), typeof(int) };

        // Create an unnamed dynamic method with a return type of 
        // int and with two parameters whose types are specified by 
        // the array paramTypes. This constructor does not associate the  
        // dynamic method with a module or type, so the dynamic method 
        // is hosted in an anonymous dynamic assembly.  
        DynamicMethod meth =
            new DynamicMethod("", typeof(int), paramTypes);

        // Get a MethodInfo for the overload of Console.WriteLine that 
        // takes one string argument (that is, no format string). The 
        // dynamic method uses this overload to display  
        // strings.
        MethodInfo writeString = typeof(Console).GetMethod(
            "WriteLine", 
            new Type[] { typeof(String) });

        // Get an ILGenerator and emit a body for the dynamic method.
        ILGenerator il = meth.GetILGenerator();

        // Load the first argument, which is a string, onto the stack. 
        // Call the overload of Console.WriteLine that prints a string.         
        il.Emit(OpCodes.Ldarg_0);
        il.EmitCall(OpCodes.Call, writeString, null);

        // Optionally emit a method call that requires FileIOPermission. 
        if (requiresPermissions)
        {
            // Get a MethodInfo for the Directory.GetCurrentDirectory 
            // method. 
            MethodInfo currDirectory = 
                typeof(Directory).GetMethod("GetCurrentDirectory");

            // Call GetCurrentDirectory, to push the current directory name 
            // onto the execution stack. Then call WriteLine to display it.
            il.EmitCall(OpCodes.Call, currDirectory, null);
            il.EmitCall(OpCodes.Call, writeString, null);
        }

        // The method returns the value of the second argument; to do 
        // this, load the second argument onto the execution stack and  
        // return.
        il.Emit(OpCodes.Ldarg_1);
        il.Emit(OpCodes.Ret);

        // Return a delegate that represents the dynamic method. This 
        // action completes the dynamic method, and any further attempts 
        // to change the method have no effect. 
        return (Test) meth.CreateDelegate(typeof(Test));
    }
}

/* This code example produces output similar to the following:

Hello, World!
Executing delegate testMeth("Hello, World!", 42) returned: 42

Hello, World!
Executing the delegate caused a SecurityException:
Request for the permission of type 'System.Security.Permissions.FileIOPermission,
 mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.
 */

Windows 7, Windows Vista, Windows XP SP2, Windows Server 2008 R2, Windows Server 2008, Windows Server 2003

The .NET Framework and .NET Compact Framework do not support all versions of every platform. For a list of the supported versions, see .NET Framework System Requirements.

.NET Framework

Supported in: 3.5 SP1, 3.0 SP1, 2.0 SP1
Show: