C# IsDefined的問題_C#教程

來源:互聯網
上載者:User

在.NET 4.0(當然也包括4.0以前的版本)下,用反射判斷某個方法是否運用了自訂Attribute時,可以通過調用MethodInfo的IsDefined()方法進行確認。當然,IsDefined()方法事實上定義在MethodInfo的父類MemberInfo中,但它僅僅被定義為抽象方法,真正的實現是在MethodInfo的子類DynamicMethod中。調用方式如下所示:

複製代碼 代碼如下:
methodInfo.IsDefined(typeof(MyAttribute), false)

然而,在實際開發中,我發現該方法有一個問題。如果獲得MethodInfo的方式是通過載入程式集,然後利用反射方式獲得的MethodInfo對象,即使該方法運用了自訂Attribute,返回的結果仍然是false。例如,我們將需要判斷的方法所在的類定義到一個單獨的Project中,並編譯為單獨的dll檔案,然後,利用Assembly的LoadFile()方式獲得程式集:

複製代碼 代碼如下:
var assembly = Assembly.LoadFile(assemblyPath);
var types = assembly.GetExportedTypes();
types.ToList().ForEach(
  type =>
  {
      var flag =
          type.GetMethods().Where(methodInfo => !methodInfo.IsAbstract).Any(
              methodInfo => methodInfo.IsDefined(typeof(MyAttribute), false));
      Console.WriteLine("Flag of IsDefined is: {0}", flag);
  }
);

列印出來的值為false。

反之,如果不是通過載入程式集,而是直接通過typeof()獲得的Type,並調用其下MethodInfo.IsDefined()方法,只要該方法被運用了指定的Attribute,返回的結果則為true。

分析原因,大約是獲得Type的方式不同所造成的。Assembly類的GetExportedType()實現如下所示:

複製代碼 代碼如下:
[SecuritySafeCritical]
public override Type[] GetExportedTypes()
{
    Type[] o = null;
    GetExportedTypes(this.GetNativeHandle(), JitHelpers.GetObjectHandleOnStack<Type[]>(ref o));
    return o;
}

注意,這裡返回的Type[]事實上是通過引用方式傳遞給了JitHelpers的GetObjectHandleOnStack<Type[]>方法中:

複製代碼 代碼如下:
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), SecurityCritical]
internal static ObjectHandleOnStack GetObjectHandleOnStack<T>(ref T o) where T: class
{
    TypedReference reference = __makeref(o);
    return new ObjectHandleOnStack(reference.GetPointerOnStack());
}

這裡將Type轉換成了TypedReference。關鍵大約就是這裡,可惜我無法找到typeof()的具體實現方式。代碼追蹤到這裡,就無法判斷這裡發生的真實原因了。若要瞭解.NET底層機制的同學,可以告訴我。

若要解決反射方式無法通過IsDefined()判斷的問題,可以調用MethodInfo的GetCustomAttribute()方法。例如:

複製代碼 代碼如下:
private static bool IsAppliedWith(this MethodInfo methodInfo, Type attributeType, string attributeName)
{
    return methodInfo.GetCustomAttributes(attributeType, false).ToString().Contains(attributeName);
}

無論是利用反射載入,還是使用typeof,採用這種方式判斷方法是否運用了指定的Attribute,都是能夠生效的。

以上就是C#IsDefined的問題的全部內容,希望能給大家一個參考,也希望大家多多支援雲棲社區。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.