내보내기(0) 인쇄
모두 확장

MethodBuilder.SetSignature 메서드

참고: 이 메서드는 .NET Framework 버전 2.0에서 새로 추가되었습니다.

반환 형식, 매개 변수 형식, 반환 형식과 매개 변수 형식의 필수적 및 선택적 사용자 지정 한정자가 포함된 메서드 시그니처를 설정합니다.

네임스페이스: System.Reflection.Emit
어셈블리: mscorlib(mscorlib.dll)

public void SetSignature (
	Type returnType,
	Type[] returnTypeRequiredCustomModifiers,
	Type[] returnTypeOptionalCustomModifiers,
	Type[] parameterTypes,
	Type[][] parameterTypeRequiredCustomModifiers,
	Type[][] parameterTypeOptionalCustomModifiers
)
public void SetSignature (
	Type returnType, 
	Type[] returnTypeRequiredCustomModifiers, 
	Type[] returnTypeOptionalCustomModifiers, 
	Type[] parameterTypes, 
	Type[][] parameterTypeRequiredCustomModifiers, 
	Type[][] parameterTypeOptionalCustomModifiers
)
public function SetSignature (
	returnType : Type, 
	returnTypeRequiredCustomModifiers : Type[], 
	returnTypeOptionalCustomModifiers : Type[], 
	parameterTypes : Type[], 
	parameterTypeRequiredCustomModifiers : Type[][], 
	parameterTypeOptionalCustomModifiers : Type[][]
)

매개 변수

returnType

메서드의 반환 형식입니다.

returnTypeRequiredCustomModifiers

메서드의 반환 형식에 대한 필수적 사용자 지정 한정자(예: IsConst)를 나타내는 형식의 배열입니다. 반환 형식에 필수적 사용자 지정 한정자가 없으면 Null 참조(Visual Basic의 경우 Nothing)을 지정합니다.

returnTypeOptionalCustomModifiers

메서드의 반환 형식에 대한 선택적 사용자 지정 한정자(예: IsConst)를 나타내는 형식의 배열입니다. 반환 형식에 필수적 사용자 지정 한정자가 없으면 Null 참조(Visual Basic의 경우 Nothing)을 지정합니다.

parameterTypes

메서드의 매개 변수 형식입니다.

parameterTypeRequiredCustomModifiers

형식 배열로 이루어진 배열입니다. 각 형식 배열은 해당되는 매개 변수의 필수적 사용자 지정 한정자(예: IsConst)를 나타냅니다. 특정 매개 변수에 필수적 사용자 지정 한정자가 없는 경우에는 형식 배열 대신 Null 참조(Visual Basic의 경우 Nothing)을 지정합니다. 모든 매개 변수에 필수적 사용자 지정 한정자가 없는 경우에는 배열로 이루어진 배열 대신 Null 참조(Visual Basic의 경우 Nothing)을 지정합니다.

parameterTypeOptionalCustomModifiers

형식 배열로 이루어진 배열입니다. 각 형식 배열은 해당되는 매개 변수의 선택적 사용자 지정 한정자(예: IsConst)를 나타냅니다. 특정 매개 변수에 선택적 사용자 지정 한정자가 없는 경우에는 형식 배열 대신 Null 참조(Visual Basic의 경우 Nothing)을 지정합니다. 모든 매개 변수에 선택적 사용자 지정 한정자가 없는 경우에는 배열로 이루어진 배열 대신 Null 참조(Visual Basic의 경우 Nothing)을 지정합니다.

예외 형식조건

InvalidOperationException

현재 메서드가 제네릭 메서드이지만 제네릭 메서드 정의가 아닌 경우. 즉, IsGenericMethod 속성이 true로 설정되어 있지만 IsGenericMethodDefinition 속성은 false로 설정되어 있습니다.

메서드를 정의할 때 반환 형식과 매개 변수의 개수와 형식을 알고 있는 경우에는 매개 변수 형식의 배열을 받아들이는 모든 System.Reflection.Emit.TypeBuilder.DefineMethod 메서드 오버로드를 사용하여 해당 정보를 설정할 수 있습니다. 그러나 하나 이상의 고유한 제네릭 형식 매개 변수를 사용하여 형식을 지정해야 하는 매개 변수가 제네릭 메서드에 있는 경우에는 메서드를 정의한 후에 해당 형식 매개 변수를 정의할 수 있습니다. 이 경우에는 이 메서드를 사용하여 매개 변수 형식을 정의해야 합니다.

반환 형식과 매개 변수 형식에 모두 선택적 또는 필수적 사용자 지정 한정자(예: IsConstModifier)가 없는 경우에는 SetReturnTypeSetParameters 메서드를 사용할 수 있습니다.

이 메서드를 호출하면 System.Reflection.Emit.TypeBuilder.DefineMethod 메서드를 사용하여 설정한 매개 변수와 반환 형식이 대체됩니다.

다음 코드 예제에는 형식 매개 변수 T가 있는 제네릭 클래스 Sample에 대한 소스 코드가 포함되어 있습니다. 이 클래스에는 T 형식의 Field 필드와 고유한 형식 매개 변수 U를 사용하는 제네릭 메서드 GM이 있습니다. GM 메서드는 고유한 형식 매개 변수 U로 Sample의 형식 매개 변수를 대체하여 Sample의 인스턴스를 만들고 해당 입력 매개 변수를 Field에 저장합니다. 이 소스 코드는 컴파일되지만 사용되지는 않습니다. MSIL 디스어셈블러(Ildasm.exe)를 사용하여 이 코드를 보고 Example 클래스를 통해 생성된 코드와 비교할 수 있습니다.

Example 클래스의 코드는 제네릭 코드를 생성할 때 SetSignature 메서드를 사용하는 방법을 보여 줍니다. Example 클래스의 Main 메서드는 Sample 클래스가 들어 있는 동적 어셈블리를 만든 다음 TypeBuilder.DefineGenericParameters 메서드로 T 형식 매개 변수를 추가하여 이를 제네릭으로 만듭니다. 그러면 기본 생성자와 Field라는 T 형식의 필드가 Sample 클래스에 추가됩니다. GM 메서드가 추가되고 DefineGenericParameters 메서드를 통해 제네릭 메서드로 변경됩니다. GM의 형식 매개 변수 이름은 U입니다. 형식 매개 변수가 정의된 후에는 SetSignature 메서드를 사용하여 GM의 시그니처가 추가됩니다. 반환 형식이나 필수적 또는 선택적 사용자 지정 한정자가 없으므로 이 메서드의 모든 매개 변수는 Null 참조(Visual Basic의 경우 Nothing)입니다. 단, 이 메서드에서 유일하게 매개 변수 형식을 설정하는 parameterTypes는 제외되는데, 이는 메서드의 형식 매개 변수인 U로 설정됩니다. 이 메서드의 본문은 생성된 형식 Sample<U>(Visual Basic의 경우 Sample(Of U))의 인스턴스를 만들고 Field에 메서드의 매개 변수를 할당한 다음 Field의 값을 출력합니다. 진입점 메서드 Main를 보유하기 위해 더미 형식이 정의됩니다. Main의 본문에서는 생성된 제네릭 형식 Sample<int>(Visual Basic의 경우 Sample(Of Integer))에 대해 UString 형식으로 대체하여 정적 GM 메서드를 호출합니다. TypeBuilder.GetMethod 메서드는 생성된 제네릭 형식 Sample<U>의 정적 GM 메서드에 대한 MethodInfo를 만드는 데 사용되고, MethodInfo.MakeGenericMethod 메서드는 메서드 호출에 내보낼 수 있는 MethodInfo를 만드는 데 사용됩니다.

코드 예제를 실행하면 생성된 어셈블리가 TypeBuilderGetFieldExample.exe로 저장됩니다. TypeBuilderGetFieldExample.exe를 실행한 후 MSIL 디스어셈블러(Ildasm.exe)를 사용하면 코드 예제 자체에 컴파일된 Sample 클래스의 코드와 이 코드를 비교할 수 있습니다.

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

// Compare the MSIL in this class to the MSIL
// generated by the Reflection.Emit code in class
// Example.
public class Sample<T>
{
  public T Field;
  public static void GM<U>(U val)
  {
    Sample<U> s = new Sample<U>();
    s.Field = val;
    Console.WriteLine(s.Field);
  }
}

public class Example
{
    public static void Main()
    {
        AppDomain myDomain = AppDomain.CurrentDomain;
        AssemblyName myAsmName = 
            new AssemblyName("TypeBuilderGetFieldExample");
        AssemblyBuilder myAssembly = myDomain.DefineDynamicAssembly(
            myAsmName, AssemblyBuilderAccess.Save);
        ModuleBuilder myModule = myAssembly.DefineDynamicModule(
            myAsmName.Name, 
            myAsmName.Name + ".exe");

        // Define the sample type.
        TypeBuilder myType = myModule.DefineType("Sample", 
            TypeAttributes.Class | TypeAttributes.Public);

        // Add a type parameter, making the type generic.
        string[] typeParamNames = {"T"};  
        GenericTypeParameterBuilder[] typeParams = 
            myType.DefineGenericParameters(typeParamNames);

        // Define a default constructor. Normally it would 
        // not be necessary to define the default constructor,
        // but in this case it is needed for the call to
        // TypeBuilder.GetConstructor, which gets the default
        // constructor for the generic type constructed from 
        // Sample<T>, in the generic method GM<U>.
        ConstructorBuilder ctor = myType.DefineDefaultConstructor(
            MethodAttributes.PrivateScope | MethodAttributes.Public |
            MethodAttributes.HideBySig | MethodAttributes.SpecialName |
            MethodAttributes.RTSpecialName);

        // Add a field of type T, with the name Field.
        FieldBuilder myField = myType.DefineField("Field", 
            typeParams[0],
            FieldAttributes.Public);

        // Add a method and make it generic, with a type 
        // parameter named U. Note how similar this is to 
        // the way Sample is turned into a generic type. The
        // method has no signature, because the type of its
        // only parameter is U, which is not yet defined.
        MethodBuilder genMethod = myType.DefineMethod("GM", 
            MethodAttributes.Public | MethodAttributes.Static);
        string[] methodParamNames = {"U"};
        GenericTypeParameterBuilder[] methodParams = 
            genMethod.DefineGenericParameters(methodParamNames);
        
        // Now add a signature for genMethod, specifying U
        // as the type of the parameter. There is no return value
        // and no custom modifiers.
        genMethod.SetSignature(null, null, null, 
            new Type[] { methodParams[0] }, null, null);

        // Emit a method body for the generic method.
        ILGenerator ilg = genMethod.GetILGenerator();
        // Construct the type Sample<U> using MakeGenericType.
        Type SampleOfU = myType.MakeGenericType( methodParams[0] );
        // Create a local variable to store the instance of
        // Sample<U>.
        ilg.DeclareLocal(SampleOfU);
        // Call the default constructor. Note that it is 
        // necessary to have the default constructor for the
        // constructed generic type Sample<U>; use the 
        // TypeBuilder.GetConstructor method to obtain this 
        // constructor.
        ConstructorInfo ctorOfU = TypeBuilder.GetConstructor(
            SampleOfU, ctor);
        ilg.Emit(OpCodes.Newobj, ctorOfU);
        // Store the instance in the local variable; load it
        // again, and load the parameter of genMethod.
        ilg.Emit(OpCodes.Stloc_0); 
        ilg.Emit(OpCodes.Ldloc_0); 
        ilg.Emit(OpCodes.Ldarg_0);
        // In order to store the value in the field of the
        // instance of Sample<U>, it is necessary to have 
        // a FieldInfo representing the field of the 
        // constructed type. Use TypeBuilder.GetField to 
        // obtain this FieldInfo.
        FieldInfo FieldOfU = TypeBuilder.GetField(
            SampleOfU, myField);
        // Store the value in the field. 
        ilg.Emit(OpCodes.Stfld, FieldOfU);
        // Load the instance, load the field value, box it
        // (specifying the type of the type parameter, U), and
        // print it.
        ilg.Emit(OpCodes.Ldloc_0);
        ilg.Emit(OpCodes.Ldfld, FieldOfU);
        ilg.Emit(OpCodes.Box, methodParams[0]);
        MethodInfo writeLineObj = 
            typeof(Console).GetMethod("WriteLine", 
                new Type[] { typeof(object) });
        ilg.EmitCall(OpCodes.Call, writeLineObj, null);
        ilg.Emit(OpCodes.Ret);

        // Emit an entry point method; this must be in a
        // non-generic type.
        TypeBuilder dummy = myModule.DefineType("Dummy", 
            TypeAttributes.Class | TypeAttributes.NotPublic);
        MethodBuilder entryPoint = dummy.DefineMethod("Main", 
            MethodAttributes.Public | MethodAttributes.Static,
            null, null);
        ilg = entryPoint.GetILGenerator();
        // In order to call the static generic method GM, it is
        // necessary to create a constructed type from the 
        // generic type definition for Sample. This can be any
        // constructed type; in this case Sample<int> is used.
        Type SampleOfInt = 
            myType.MakeGenericType( typeof(int) );
        // Next get a MethodInfo representing the static generic
        // method GM on type Sample<int>.
        MethodInfo SampleOfIntGM = TypeBuilder.GetMethod(SampleOfInt, 
            genMethod);
        // Next get a MethodInfo for GM<string>, which is the 
        // instantiation of GM that Main calls.
        MethodInfo GMOfString = 
            SampleOfIntGM.MakeGenericMethod( typeof(string) );
        // Finally, emit the call. Push a string onto
        // the stack, as the argument for the generic method.
        ilg.Emit(OpCodes.Ldstr, "Hello, world!");
        ilg.EmitCall(OpCodes.Call, GMOfString, null);
        ilg.Emit(OpCodes.Ret);

        myType.CreateType();
        dummy.CreateType();
        myAssembly.SetEntryPoint(entryPoint);
        myAssembly.Save(myAsmName.Name + ".exe");

        Console.WriteLine(myAsmName.Name + ".exe has been saved.");
    }
}

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에서 모든 플래폼의 모든 버전을 지원하지는 않습니다. 지원되는 버전의 목록은 시스템 요구 사항을 참조하십시오.

.NET Framework

2.0에서 지원

커뮤니티 추가 항목

추가
표시:
© 2014 Microsoft