MethodBuilder.SetSignature 메서드
정의
중요
일부 정보는 릴리스되기 전에 상당 부분 수정될 수 있는 시험판 제품과 관련이 있습니다. Microsoft는 여기에 제공된 정보에 대해 어떠한 명시적이거나 묵시적인 보증도 하지 않습니다.
반환 형식, 매개 변수 형식, 반환 형식과 매개 변수 형식의 필수 및 선택적 사용자 지정 한정자를 포함하여 메서드 시그니처를 설정합니다.
public:
void SetSignature(Type ^ returnType, cli::array <Type ^> ^ returnTypeRequiredCustomModifiers, cli::array <Type ^> ^ returnTypeOptionalCustomModifiers, cli::array <Type ^> ^ parameterTypes, cli::array <cli::array <Type ^> ^> ^ parameterTypeRequiredCustomModifiers, cli::array <cli::array <Type ^> ^> ^ parameterTypeOptionalCustomModifiers);
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);
member this.SetSignature : Type * Type[] * Type[] * Type[] * Type[][] * Type[][] -> unit
Public Sub SetSignature (returnType As Type, returnTypeRequiredCustomModifiers As Type(), returnTypeOptionalCustomModifiers As Type(), parameterTypes As Type(), parameterTypeRequiredCustomModifiers As Type()(), parameterTypeOptionalCustomModifiers As Type()())
매개 변수
- returnType
- Type
메서드의 반환 형식입니다.
- returnTypeRequiredCustomModifiers
- Type[]
메서드의 반환 형식에 대한 필수 사용자 지정 한정자를 나타내는 형식의 배열(예: IsConst)입니다. 반환 형식에 필수 사용자 지정 한정자가 없으면 null
을 지정합니다.
- returnTypeOptionalCustomModifiers
- Type[]
메서드의 반환 형식에 대한 선택적 사용자 지정 한정자를 나타내는 형식의 배열(예: IsConst)입니다. 반환 형식에 선택적 사용자 지정 한정자가 없으면 null
을 지정합니다.
- parameterTypes
- Type[]
메서드의 매개 변수 형식입니다.
- parameterTypeRequiredCustomModifiers
- Type[][]
형식 배열의 배열입니다. 각 형식의 배열은 해당 매개 변수에 필요한 사용자 지정 한정자를 나타냅니다(예: IsConst). 특정 매개 변수에 필수 사용자 지정 한정자가 없는 경우 형식 배열 대신 null
을 지정합니다. 매개 변수에 필수 사용자 지정 한정자가 없는 경우 형식 배열 대신 null
을 지정합니다.
- parameterTypeOptionalCustomModifiers
- Type[][]
형식 배열의 배열입니다. 각 형식의 배열은 해당 매개 변수의 선택적 사용자 지정 한정자를 나타냅니다(예: IsConst). 특정 매개 변수에 선택적 사용자 지정 한정자가 없는 경우 형식 배열 대신 null
을 지정합니다. 매개 변수에 선택적 사용자 지정 한정자가 없는 경우 형식 배열 대신 null
을 지정합니다.
예외
현재 메서드는 제네릭이지만 제네릭 메서드 정의는 아닙니다. 즉, IsGenericMethod 속성은 true
지만 IsGenericMethodDefinition 속성은 false
입니다.
예제
다음 코드 예제에는 형식 매개 변수 T
가 있는 Sample이라는 제네릭 클래스에 대한 소스 코드가 포함되어 있습니다. 클래스에는 형식의 라는 Field
필드와 고유한 형식 T
매개 변수 가 있는 제네릭 메서드 GM
가 U
있습니다. 메서드 GM
는 Sample의 instance 만들고 Sample의 형식 매개 변수에 대한 고유한 형식 매개 변수 U
를 대체하고 입력 매개 변수를 에 Field
저장합니다. 이 소스 코드는 컴파일되지만 사용되지 않습니다. Ildasm.exe(IL 디스어셈블러)로 보고 클래스 Example
에서 내보낸 코드와 비교할 수 있습니다.
클래스 Example
의 코드는 제네릭 코드를 내보내는 SetSignature 데 메서드를 사용하는 방법을 보여 줍니다. 클래스 Example
의 메서드는 Main
라는 Sample
클래스를 포함하는 동적 어셈블리를 만들고 메서드를 TypeBuilder.DefineGenericParameters 사용하여 라는 T
형식 매개 변수를 추가하여 제네릭으로 만듭니다. 매개 변수가 없는 생성자 및 형식T
의 라는 Field
필드가 클래스 Sample
에 추가됩니다. 메서드가 추가되고 메서드 GM
를 사용하여 제네릭 메서드로 변환됩니다 DefineGenericParameters . 의 GM
형식 매개 변수 이름은 U
입니다. 형식 매개 변수가 정의되면 메서드를 사용하여 의 GM
서명이 SetSignature 추가됩니다. 반환 형식이 없고 필수 또는 사용자 지정 한정자가 없으므로 이 메서드의 모든 매개 변수는 를 제외하고 parameterTypes
메서드의 유일한 매개 변수 형식을 설정합니다. 이 매개 변수는 메서드의 형식 매개 변수 로 U
설정됩니다null
. 메서드의 본문은 생성된 형식 Sample<U>
(Visual Basic의 경우)Sample(Of U)
의 instance 만들고 메서드의 매개 변수를 Field
에 할당한 다음 의 Field
값을 출력합니다. 진입점 메서드 Main
를 보유하기 위해 더미 형식이 정의됩니다. 본 Main
문에서 정적 GM
메서드는 생성된 제네릭 형식 Sample<int>
(Visual Basic의 경우)Sample(Of Integer)
에서 호출되고 형식 String 은 로 대체됩니다 U
. 메서드는 TypeBuilder.GetMethod 생성된 제네릭 형식Sample<U>
의 정적 GM
메서드에 대한 를 만드는 MethodInfo 데 사용되며 MethodInfo.MakeGenericMethod 메서드는 메서드 호출에서 내보낼 수 있는 을 만드는 MethodInfo 데 사용됩니다.
코드 예제가 실행되면 내보낸 어셈블리를 TypeBuilderGetFieldExample.exe 저장합니다. TypeBuilderGetFieldExample.exe 실행할 수 있으며 Ildasm.exe(IL 디스어셈블러) 을 사용하여 내보낸 코드를 코드 예제 자체로 컴파일된 클래스의 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.");
}
}
Imports System.Reflection
Imports System.Reflection.Emit
' Compare the MSIL in this class to the MSIL
' generated by the Reflection.Emit code in class
' Example.
Public Class Sample(Of T)
Public Field As T
Public Shared Sub GM(Of U)(ByVal val As U)
Dim s As New Sample(Of U)
s.Field = val
Console.WriteLine(s.Field)
End Sub
End Class
Public Class Example
Public Shared Sub Main()
Dim myDomain As AppDomain = AppDomain.CurrentDomain
Dim myAsmName As New AssemblyName("TypeBuilderGetFieldExample")
Dim myAssembly As AssemblyBuilder = _
myDomain.DefineDynamicAssembly(myAsmName, _
AssemblyBuilderAccess.Save)
Dim myModule As ModuleBuilder = _
myAssembly.DefineDynamicModule(myAsmName.Name, _
myAsmName.Name & ".exe")
' Define the sample type.
Dim myType As TypeBuilder = myModule.DefineType( _
"Sample", _
TypeAttributes.Class Or TypeAttributes.Public)
' Add a type parameter, making the type generic.
Dim typeParamNames() As String = { "T" }
Dim typeParams As GenericTypeParameterBuilder() = _
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(Of T), in the generic method GM(Of U).
Dim ctor As ConstructorBuilder = _
myType.DefineDefaultConstructor( _
MethodAttributes.PrivateScope Or MethodAttributes.Public _
Or MethodAttributes.HideBySig Or MethodAttributes.SpecialName _
Or MethodAttributes.RTSpecialName)
' Add a field of type T, with the name Field.
Dim myField As FieldBuilder = 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.
Dim genMethod As MethodBuilder = _
myType.DefineMethod("GM", _
MethodAttributes.Public Or MethodAttributes.Static)
Dim methodParamNames() As String = { "U" }
Dim methodParams As GenericTypeParameterBuilder() = _
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(Nothing, Nothing, Nothing, _
New Type() { methodParams(0) }, Nothing, Nothing)
' Emit a method body for the generic method.
Dim ilg As ILGenerator = genMethod.GetILGenerator()
' Construct the type Sample(Of U) using MakeGenericType.
Dim SampleOfU As Type = _
myType.MakeGenericType(methodParams(0))
' Create a local variable to store the instance of
' Sample(Of U).
ilg.DeclareLocal(SampleOfU)
' Call the default constructor. Note that it is
' necessary to have the default constructor for the
' constructed generic type Sample(Of U); use the
' TypeBuilder.GetConstructor method to obtain this
' constructor.
Dim ctorOfU As ConstructorInfo = _
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(Of U), it is necessary to have
' a FieldInfo representing the field of the
' constructed type. Use TypeBuilder.GetField to
' obtain this FieldInfo.
Dim FieldOfU As FieldInfo = _
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))
Dim writeLineObj As MethodInfo = _
GetType(Console).GetMethod("WriteLine", _
New Type() {GetType(Object)})
ilg.EmitCall(OpCodes.Call, writeLineObj, Nothing)
ilg.Emit(OpCodes.Ret)
' Emit an entry point method; this must be in a
' non-generic type.
Dim dummy As TypeBuilder = _
myModule.DefineType("Dummy", _
TypeAttributes.Class Or TypeAttributes.NotPublic)
Dim entryPoint As MethodBuilder = _
dummy.DefineMethod("Main", _
MethodAttributes.Public Or MethodAttributes.Static, _
Nothing, Nothing)
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(Of Integer)
' is used.
Dim SampleOfInt As Type = _
myType.MakeGenericType(GetType(Integer))
' Next get a MethodInfo representing the static generic
' method GM on type Sample(Of Integer).
Dim SampleOfIntGM As MethodInfo = _
TypeBuilder.GetMethod(SampleOfInt, genMethod)
' Next get a MethodInfo for GM(Of String), which is the
' instantiation of generic method GM that is called
' by Sub Main.
Dim GMOfString As MethodInfo = _
SampleOfIntGM.MakeGenericMethod(GetType(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, Nothing)
ilg.Emit(OpCodes.Ret)
myType.CreateType()
dummy.CreateType()
myAssembly.SetEntryPoint(entryPoint)
myAssembly.Save(myAsmName.Name & ".exe")
Console.WriteLine(myAsmName.Name & ".exe has been saved.")
End Sub
End Class
설명
메서드가 정의될 때 반환 형식과 매개 변수의 수 및 형식이 알려진 경우 매개 변수 형식의 배열을 허용하는 메서드의 TypeBuilder.DefineMethod 오버로드를 사용하여 설정할 수 있습니다. 그러나 제네릭 메서드에는 하나 이상의 고유한 제네릭 형식 매개 변수에 의해 형식이 지정된 매개 변수가 있을 수 있으며, 메서드가 정의될 때까지 정의할 수 없습니다. 이 경우 매개 변수 형식을 설정하려면 이 메서드를 사용합니다.
반환 형식이나 매개 변수 형식에 선택적 또는 필요한 사용자 지정 한정자(예: IsConstModifier)가 없는 경우 및 SetParameters 메서드를 SetReturnType 사용할 수 있습니다.
이 메서드를 호출하면 메서드를 사용하여 설정된 매개 변수 및 반환 형식이 TypeBuilder.DefineMethod 대체됩니다.
적용 대상
추가 정보
.NET