<메서드> 요소(.NET 네이티브)
생성자 또는 메서드에 런타임 리플렉션 정책을 적용합니다.
구문
<Method Name="method_name"
Signature="method_signature"
Browse="policy_type"
Dynamic="policy_type" />
특성 및 요소
다음 단원에서는 특성, 자식 요소 및 부모 요소에 대해 설명합니다.
특성
Attribute | 특성 유형 | 설명 |
---|---|---|
Name |
일반 | 필수 특성입니다. 메서드 이름을 지정합니다. |
Signature |
일반 | 선택적 특성입니다. 메서드 시그니처를 지정합니다. 매개 변수가 여러 개이면 쉼표로 구분합니다. 예를 들어 다음 <Method> 요소는 ToString(String, IFormatProvider) 메서드에 대한 정책을 정의합니다.<Type Name="System.DateTime"> <Method Name="ToString" Signature="System.String,System.IFormatProvider" Dynamic="Required" /> </Type> 특성이 없으면 런타임 지시문은 메서드의 모든 오버로드에 적용됩니다. |
Browse |
반영 | 선택적 특성입니다. 메서드에 대한 정보 쿼리 또는 메서드 열거는 제어하지만 런타임에 동적 호출을 사용하도록 설정하지는 않습니다. |
Dynamic |
반영 | 선택적 특성입니다. 동적 프로그래밍을 수행할 수 있도록 생성자 또는 메서드에 대한 런타임 액세스를 제어합니다. 이 정책을 사용하면 런타임에 멤버를 동적으로 호출할 수 있습니다. |
Name 특성
값 | 설명 |
---|---|
method_name | 메서드 이름입니다. 메서드의 형식은 부모 <Type> 또는 <TypeInstantiation> 요소로 정의됩니다. |
시그니처 특성
값 | 설명 |
---|---|
method_signature | 메서드 시그니처를 구성하는 매개 변수 형식입니다. 매개 변수가 여러 개이면 "System.String,System.Int32,System.Int32)" 와 같이 쉼표로 구분합니다. 매개 변수 형식 이름은 정규화해야 합니다. |
기타 모든 특성
값 | 설명 |
---|---|
policy_setting | 이 정책 형식에 적용할 설정입니다. 가능한 값은 Auto , Excluded , Included 및 Required 입니다. 자세한 내용은 런타임 지시문 정책 설정을 참조하세요. |
자식 요소
요소 | 설명 |
---|---|
<매개 변수> | 메서드에 전달된 인수의 형식에 정책을 적용합니다. |
<GenericParameter> | 제네릭 형식 또는 메서드의 매개 변수 형식에 정책을 적용합니다. |
<ImpliesType> | 포함 <Method> 요소가 나타내는 메서드에 정책이 적용된 경우 형식에 해당 정책을 적용합니다. |
<TypeParameter> | 메서드로 전달된 Type 인수가 나타내는 형식에 정책을 적용합니다. |
부모 요소
요소 | 설명 |
---|---|
<형식> | 형식 및 모든 해당 멤버에 리플렉션 정책을 적용합니다. |
<TypeInstantiation> | 생성된 제네릭 형식 및 모든 해당 멤버에 리플렉션 정책을 적용합니다. |
설명
제네릭 메서드의 <Method>
요소는 자체 정책이 없는 모든 인스턴스화에 해당 정책을 적용합니다.
Signature
특성을 사용하여 특정 메서드 오버로드에 대한 정책을 지정할 수 있습니다. Signature
특성이 없는 경우 런타임 지시문은 메서드의 모든 오버로드에 적용됩니다.
<Method>
요소를 사용하여 생성자에 대해 런타임 리플렉션 정책을 정의할 수는 없습니다. 대신 <Assembly>, <Namespace>, <Type> 또는 <TypeInstantiation> 요소의 Activate
특성을 사용합니다.
예시
다음 예제의 Stringify
메서드는 리플렉션을 사용하여 개체를 문자열 표현으로 변환하는 범용 서식 지정 메서드입니다. 이 메서드는 개체의 기본 ToString
메서드를 호출할 수 있을 뿐 아니라 개체의 ToString
메서드에 서식 문자열이나 IFormatProvider 구현 중 하나 또는 둘 다를 전달하여 서식이 지정된 결과 문자열을 생성할 수도 있습니다. 또한 숫자를 이진, 16진수 또는 8진수 표현으로 변환하는 Convert.ToString 오버로드 중 하나를 호출할 수도 있습니다.
public class Stringify
{
public static string ConvertToString(Object[] obj)
{
if (obj == null)
throw new NullReferenceException("The obj parameter cannot be null.");
if (obj.Length == 0) return String.Empty;
if (obj[0].GetType() == typeof(String))
return obj[0] as string;
if (obj.Length == 1) return obj[0].ToString();
if (obj.Length > 3)
throw new ArgumentOutOfRangeException("The array can have from zero to three elements.");
string retval = "";
// Parameters indicate either a format specifier, numeric base, or format provider,
// or a format specifier with an IFormatProvider.
// A string as the first parameter indicates a format specifier.
if (obj[1].GetType() == typeof(String)) {
Type t = obj[0].GetType();
if (obj.Length == 2)
{
MethodInfo m = t.GetRuntimeMethod("ToString", new Type[] { typeof(String) });
retval = m.Invoke(obj[0], new object[] { obj[1] }).ToString();
}
else
{
MethodInfo m = t.GetRuntimeMethod("ToString", new Type[] { typeof(String), obj[2].GetType() });
retval = m.Invoke(obj[0], new object[] { obj[1], obj[2] }).ToString();
}
}
else if (obj[1] is IFormatProvider)
{
Type t = obj[0].GetType();
MethodInfo m = t.GetRuntimeMethod("ToString", new Type[] { obj[1].GetType() } );
retval = m.Invoke(obj[0], new object[] { obj[1] }).ToString();
}
// The second parameter is a base, so call Convert.ToString(number, int).
else {
Type t = typeof(Convert);
MethodInfo m = t.GetRuntimeMethod("ToString", new Type[] { obj[0].GetType(), obj[1].GetType() } );
retval = m.Invoke(null, obj).ToString();
}
return retval;
}
}
다음과 같은 코드를 통해 Stringify
메서드를 호출할 수 있습니다.
public class Stringify
{
public static string ConvertToString(Object[] obj)
{
if (obj == null)
throw new NullReferenceException("The obj parameter cannot be null.");
if (obj.Length == 0) return String.Empty;
if (obj[0].GetType() == typeof(String))
return obj[0] as string;
if (obj.Length == 1) return obj[0].ToString();
if (obj.Length > 3)
throw new ArgumentOutOfRangeException("The array can have from zero to three elements.");
string retval = "";
// Parameters indicate either a format specifier, numeric base, or format provider,
// or a format specifier with an IFormatProvider.
// A string as the first parameter indicates a format specifier.
if (obj[1].GetType() == typeof(String)) {
Type t = obj[0].GetType();
if (obj.Length == 2)
{
MethodInfo m = t.GetRuntimeMethod("ToString", new Type[] { typeof(String) });
retval = m.Invoke(obj[0], new object[] { obj[1] }).ToString();
}
else
{
MethodInfo m = t.GetRuntimeMethod("ToString", new Type[] { typeof(String), obj[2].GetType() });
retval = m.Invoke(obj[0], new object[] { obj[1], obj[2] }).ToString();
}
}
else if (obj[1] is IFormatProvider)
{
Type t = obj[0].GetType();
MethodInfo m = t.GetRuntimeMethod("ToString", new Type[] { obj[1].GetType() } );
retval = m.Invoke(obj[0], new object[] { obj[1] }).ToString();
}
// The second parameter is a base, so call Convert.ToString(number, int).
else {
Type t = typeof(Convert);
MethodInfo m = t.GetRuntimeMethod("ToString", new Type[] { obj[0].GetType(), obj[1].GetType() } );
retval = m.Invoke(null, obj).ToString();
}
return retval;
}
}
그러나 이 예제를 .NET 네이티브에서 컴파일하면 런타임에 NullReferenceException 및 MissingRuntimeArtifactException 예외를 비롯한 여러 예외가 throw될 수 있습니다. 이러한 예외가 throw되는 이유는, Stringify
메서드는 기본적으로 .NET Framework 클래스 라이브러리의 기본 형식에 대한 동적 서식 지정을 지원하는 데 사용되는데 기본 지시문 파일이 해당 메타데이터를 제공하지 않기 때문입니다. 그러나 메타데이터가 제공되더라도 위의 예제에서는 MissingRuntimeArtifactException 예외가 throw됩니다. 적절한 ToString
구현이 네이티브 코드에 포함되지 않았기 때문입니다.
<Type> 요소를 사용하여 해당 메타데이터가 있어야 하는 형식을 정의하고, <Method>
요소를 추가하여 동적으로 호출 가능한 메서드 오버로드 구현도 있어야 하도록 지정하면 이러한 예외를 방지할 수 있습니다. 다음은 이러한 예외를 방지하고 예제가 오류 없이 실행되도록 하는 default.rd.xml 파일입니다.
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
<Application>
<Assembly Name="*Application*" Dynamic="Required All" />
<Type Name = "System.Convert" Browse="Required Public" Dynamic="Required Public" >
<Method Name="ToString" Dynamic ="Required" />
</Type>
<Type Name="System.Double" Browse="Required Public">
<Method Name="ToString" Dynamic="Required" />
</Type>
<Type Name ="System.Int32" Browse="Required Public" >
<Method Name="ToString" Dynamic="Required" />
</Type>
<Type Name ="System.Int64" Browse="Required Public" >
<Method Name="ToString" Dynamic="Required" />
</Type>
<Namespace Name="System" >
<Type Name="Byte" Browse="Required Public" >
<Method Name="ToString" Dynamic="Required" />
</Type>
<Type Name="DateTime" Browse="Required Public" >
<Method Name="ToString" Dynamic="Required" />
</Type>
<Type Name="Decimal" Browse="Required Public" >
<Method Name="ToString" Dynamic="Required" />
</Type>
<Type Name="Guid" Browse ="Required Public" >
<Method Name="ToString" Dynamic="Required" />
</Type>
<Type Name="Int16" Browse="Required Public" >
<Method Name="ToString" Dynamic="Required" />
</Type>
<Type Name="SByte" Browse="Required Public" >
<Method Name="ToString" Dynamic="Required" />
</Type>
<Type Name="Single" Browse="Required Public" >
<Method Name="ToString" Dynamic="Required" />
</Type>
<Type Name="TimeSpan" Browse="Required Public" >
<Method Name="ToString" Dynamic="Required" />
</Type>
<Type Name="UInt16" Browse="Required Public" >
<Method Name="ToString" Dynamic="Required" />
</Type>
<Type Name="UInt32" Browse="Required Public" >
<Method Name="ToString" Dynamic="Required" />
</Type>
<Type Name="UInt64" Browse="Required Public" >
<Method Name="ToString" Dynamic="Required" />
</Type>
</Namespace>
</Application>
</Directives>
참고 항목
피드백
https://aka.ms/ContentUserFeedback
출시 예정: 2024년 내내 콘텐츠에 대한 피드백 메커니즘으로 GitHub 문제를 단계적으로 폐지하고 이를 새로운 피드백 시스템으로 바꿀 예정입니다. 자세한 내용은 다음을 참조하세요.다음에 대한 사용자 의견 제출 및 보기