<Method> 項目 (.NET Native)
將執行階段反映原則套用到建構函式或方法。
語法
<Method Name="method_name"
Signature="method_signature"
Browse="policy_type"
Dynamic="policy_type" />
屬性和項目
下列章節說明屬性、子元素和父元素。
屬性
屬性 | 屬性類型 | 描述 |
---|---|---|
Name |
一般 | 必要的 屬性。 指定方法名稱。 |
Signature |
一般 | 選用屬性。 指定方法簽章。 如果有多個參數存在,會以逗號分隔。 例如,下列 <Method> 元素會定義 ToString(String, IFormatProvider) 方法的原則。<Type Name="System.DateTime"> <Method Name="ToString" Signature="System.String,System.IFormatProvider" Dynamic="Required" /> </Type> 如果屬性不存在,執行階段指示詞會套用到方法的所有多載。 |
Browse |
反映 | 選用屬性。 控制對方法相關資訊的查詢,或控制方法的列舉,但不會在執行階段啟用任何動態引動過程。 |
Dynamic |
反映 | 選用屬性。 控制對建構函式或方法的執行階段存取權,以啟用動態程式設計。 此原則確保能夠在執行階段動態叫用成員。 |
Name 屬性
值 | Description |
---|---|
method_name | 方法名稱。 方法的類型是由父 <Type> 或 <TypeInstantiation> 項目所定義。 |
簽章屬性
值 | Description |
---|---|
method_signature | 構成方法簽章的參數類型。 若有多個參數,會以逗號分隔,例如,"System.String,System.Int32,System.Int32)" 。 參數類型名稱應該是完整名稱。 |
所有其他屬性
值 | Description |
---|---|
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 方法,以產生格式化的結果字串。 它也可以呼叫其中一個 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 Native 編譯時,此範例可以在運行時間擲回數個例外狀況,包括 NullReferenceException 和MissingRuntimeArtifactException 例外狀況,因為Stringify
方法主要是為了支援以動態方式格式化 .NET Framework 類別庫中的基本類型。 不過,預設指示詞檔案並沒有提供其中繼資料。 但是,即使其中繼資料可供使用,範例還是會擲回 MissingRuntimeArtifactException 例外狀況,因為適當的 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>