程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> .NET Framework源碼研究系列之---萬法歸宗Object

.NET Framework源碼研究系列之---萬法歸宗Object

編輯:關於.NET

經過前面三篇關於.NET Framework源碼研究系列的隨筆,相信大家都發現其實.NET Framework的實現其實並不復雜,也許跟我們自己做的項目開發差不多.本人也是這樣的看法.不 過,經過仔細深入的研究,我們還是會發現一下平時很難注意到的東西,而這些東西對我們完善思 路,開闊眼界,鍛煉良好的編碼素質有著很大的意義.

我們知道.NET中所有的類型(包括:引用類型,值類型)都從Object類派生過來,由此可以說 Object是所有類型的根本.那麼今天我們就研究.NET(C#)中一切元素的根本--- System.Object.

Object類在.NET源碼中的實現很簡單,一共不過100行左右的代碼,這也是我們有精力可以仔 細研究它的每一行代碼.先看它的定義.

1   [Serializable()]
2   [ClassInterface(ClassInterfaceType.AutoDual)]
3   [System.Runtime.InteropServices.ComVisible(true)]
4   public class Object

由定義來看,Object好像是一個普通的類(莫非Object也從Object派生而來?! ^_^ ).Serializable標簽說明了Object可以做序列化反序列化操作.  ClassInterface (ClassInterfaceType.AutoDual),System.Runtime.InteropServices.ComVisible(true) 是.NET為了支持COM特別設計的.除非你要手動包裝COM,否則對於絕大部分時間都是用托管代碼 而言的人沒什麼意義.

接下來看它的構造函數:

1     [ReliabilityContract(Consistency.WillNotCorruptState,  Cer.MayFail)]
2     public Object(){ }
3         [ReliabilityContract(Consistency.WillNotCorruptState,  Cer.Success)]
4        ~Object() {}

從上面的代碼看到Object只有一個空方法體的構造函數,這就是宇宙起源一樣,剛開始什麼都 沒有.此處要特別說明的是ReliabilityContract標簽.ReliabilityContract定義某些代碼的作 者和依賴於這些代碼的開發人員之間的可協靠性定。這是官方的定義,聽起來有些玄 乎.ReliabilityContract有兩個屬性,分別是兩個枚舉:Cer和ConsistencyGuarantee.Cer指在受 約束的執行區域內調用時指定方法的行為;ConsistencyGuarantee指可靠性協定。看MSDN對這兩 個枚舉的說明後,我們發現 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]為Object提供了安全性保證,就是說我們在調用Object構造函數時不管有沒有遇 到異常情況,總會獲知執行結果.

另外,Object顯式定義了析構函數(又是一個不推薦的做法,微軟好像很喜歡做的不推薦我們 做的@_@||),讓我們能夠手動釋放對象占用的資源而不需要等到GC自動釋放.

要特別說明的是,這裡有個我們很少遇到的一個概念:CER,即受約束的執行區域 , 是創作可 靠托管代碼的機制的一部分。CER 定義一個區域,在該區域中公共語言運行庫 (CLR) 會受到約 束,不能引發可使區域中的代碼無法完全執行的帶外異常。在該區域中,用戶代碼受到約束, 不能執行會導致引發帶外異常的代碼。

看完構造函數後我們看下Object中最常用的三個方法的實現,代碼如下:

public virtual String ToString(){
       return GetType().ToString();
     }
     [MethodImplAttribute(MethodImplOptions.InternalCall)]
     public extern Type GetType();
     public virtual bool Equals(Object obj){
       return InternalEquals(this, obj);
     }
     [MethodImplAttribute(MethodImplOptions.InternalCall)]
     internal static extern bool InternalEquals(Object objA, Object  objB);
     public virtual int GetHashCode(){
       return InternalGetHashCode(this);
     }
     [MethodImplAttribute(MethodImplOptions.InternalCall)]
     internal static extern int InternalGetHashCode(Object  obj);

感覺有的悲劇,因為這三個方法什麼都沒做,直接調用了CLR的內部方法,看來Object也是個馬 甲:( .微軟官方號稱Object類是所有類的基類在此恐怕要打個問號.我猜想此Object非彼 Object.說不定CLR中也有一個Object.

如果說上面三個方法有點讓人無語,那麼下面的代碼就更讓人困惑了.

private void FieldSetter(String typeName, String fieldName, Object  val){
       FieldInfo fldInfo = GetFieldInfo(typeName, fieldName);
       if (fldInfo.IsInitOnly)
         throw new FieldAccessException(Environment.GetResourceString ("FieldAccess_InitOnly"));
       System.Runtime.Remoting.Messaging.Message.CoerceArg(val,  fldInfo.FieldType);
       fldInfo.SetValue(this, val);
     }
     private void FieldGetter(String typeName, String fieldName, ref  Object val){
       FieldInfo fldInfo = GetFieldInfo(typeName, fieldName);
       val = fldInfo.GetValue(this);
     }
     private FieldInfo GetFieldInfo(String typeName, String fieldName) {
       Type t = GetType();
       while (null != t){
         if (t.FullName.Equals(typeName)){
           break;
         }
         t = t.BaseType;
       }
       if (null == t){
         throw new RemotingException(String.Format (CultureInfo.CurrentCulture, Environment.GetResourceString ("Remoting_BadType"),typeName));
       }
       FieldInfo fldInfo = t.GetField(fieldName, BindingFlags.Public  |BindingFlags.Instance |BindingFlags.IgnoreCase);
       if (null == fldInfo){
         throw new RemotingException(String.Format (CultureInfo.CurrentCulture, Environment.GetResourceString ("Remoting_BadField"),fieldName, typeName));
       }
       return fldInfo;
     }

上面一段代碼似乎讀取或設置一個字段的值(我們也是這樣的做法).問題時,我根本沒有找到 Object中用到這幾個方法的地方,private又決定了擴展類也不可能訪問.那麼這三個方法到底有 什麼用,恐怕只有微軟自己知道了.

小結

經過上面的分析,我們發現Object實現其實很簡單,幾乎沒有內容.但Object中出現的CER給我 們撰寫高安全性代碼帶來一點思考.

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved