類型基礎---CLR Via C#筆記一

 


一.全部類型都是從System.Obejct派生安全

1.下面兩個類型定義是徹底一致的:ide

1 class Employee{
2     ...
3 }
4 class Employee:System.Object{
5     ...
6 }

 

2.System.Object的公共實例方法性能

  a.Equals 判斷對象是否具備相等的值this

  b.GetHashCode 返回對象值的哈希碼spa

  c.ToString 該方法默認返回類型的完整名稱( this.GetType().FullName )3d

  d.GetType 返回從Type派生的一個對象的實例,指出調用GetType的那個對象是什麼類型指針

 

3.System.Object的受保護方法code

  a.MemberwiseClone 這個非虛方法能建立類型的新實例,並將新對象的實例字段設與this對象的實例字段徹底一致.返回的是一個對新實例的引用( 這是譯文,說實話,沒看懂,而後查閱了MSDN,其實這個方法的功能是建立一個淺表副本,是建立一個新對象,而後將當前對象的非靜態字段複製到這個淺表副本中,即新對象中.若是字段是值類型,則執行逐位複製.若是是引用類型,則複製引用而不復制引用對象,所以,原始對象及其副本引用同一對象 )對象

  如下是淺表複製和深刻複製操做的區別blog

  1     public class IdInfo
  2     {
  3         public int IdNumber;
  4 
  5         public IdInfo(int IdNumber)
  6         {
  7             this.IdNumber = IdNumber;
  8         }
  9     }
 10 
 11     public class Person
 12     {
 13         public int Age;
 14         public string Name;
 15         public IdInfo IdInfo;
 16 
 17         //淺表複製
 18         public Person ShallowCopy()
 19         {
 20             return (Person)this.MemberwiseClone();
 21         }
 22 
 23         //深刻複製
 24         public Person DeepCopy()
 25         {
 26             Person other = (Person)this.MemberwiseClone();
 27             other.IdInfo = new IdInfo(this.IdInfo.IdNumber);
 28             return other;
 29         }
 30     }
 31 
 32     class Program
 33     {
 34         public static void DisplayValues(Person p)
 35         {
 36             Console.WriteLine("Name:{0:s} , Age:{1:d}",p.Name,p.Age);
 37             Console.WriteLine("Value:{0:d}",p.IdInfo.IdNumber);
 38         }
 39 
 40         static void Main(string[] args)
 41         {
 42             //建立一個Person對象
 43             Person p1 = new Person();
 44             p1.Age = 42;
 45             p1.Name = "Sam";
 46             p1.IdInfo = new IdInfo(5042);
 47 
 48             //複製p1給p2
 49             Person p2 = (Person)p1.ShallowCopy();
 50 
 51             //展現這些值
 52             Console.WriteLine("p1實例的值");
 53             DisplayValues(p1);
 54             Console.WriteLine("p2實例的值");
 55             DisplayValues(p2);
 56 
 57             Console.WriteLine("===========改變p1值的屬性並展現p1和p2的值的時候===========");
 58 
 59             //改變p1值的屬性並展現p1和p2的值的時候
 60             p1.Age = 32;
 61             p1.Name = "Frank";
 62             p1.IdInfo.IdNumber =7080;
 63             Console.WriteLine("p1實例的值");
 64             DisplayValues(p1);
 65             Console.WriteLine("p2實例的值");
 66             DisplayValues(p2);
 67 
 68             //從結果能夠看出,淺表複製因爲引用類型複製了對象的引用,當該淺表中所對應本來對象的引用值發生改變時,則淺表中引用類型值
 69             //也會發生改變,而原對象的值類型發生改變時,淺表中值類型的值卻不會改變
 70 
 71             Console.WriteLine("===========建立一個深刻複製的對象給p3===========");
 72 
 73             //建立一個深刻複製的對象給p3
 74             Person p3 = p1.DeepCopy();
 75             p1.Name = "Gergoe";
 76             p1.Age = 22;
 77             p1.IdInfo.IdNumber = 6660;
 78             Console.WriteLine("p1實例的值");
 79             DisplayValues(p1);
 80             Console.WriteLine("p3實例的值");
 81             DisplayValues(p3);
 82 
 83             //從結果能夠看出,深刻複製是把原對象的引用類型也進行了複製,也就是說,把原對象的引用類型字段從新new了...!
 84 
 85             Console.ReadLine();
 86 
 87             //以上代碼結果:
 88             //p1實例的值
 89             //Name:Sam , Age:42
 90             //Value:5042
 91             //p2實例的值
 92             //Name:Sam , Age:42
 93             //Value:5042
 94             //===========改變p1值的屬性並展現p1和p2的值的時候===========
 95             //p1實例的值
 96             //Name:Frank , Age:32
 97             //Value:7080
 98             //p2實例的值
 99             //Name:Sam , Age:42
100             //Value:7080
101             //===========建立一個深刻複製的對象給p3===========
102             //p1實例的值
103             //Name:Gergoe , Age:22
104             //Value:6660
105             //p3實例的值
106             //Name:Frank , Age:32
107             //Value:7080
108         }
109     }
MemberwiseCopy區別深刻複製

  b.Finalize 在垃圾回收器判斷對象是否被做爲垃圾回收以後,在該對象的實際地址被回收以前,會調用這個虛方法

 

 4.CLR要求new建立對象 

1 Employee employee = new Employee("ConstructorParam1");

然而,new須要作的工做是:

  a.它計算類型及其全部基類型( 一直到System.Object )中定義字段所需的字節數.堆上每一個成員都須要一些overhead成員,即開銷成員——"類型對象指針"( type object pointer )和"同步塊索引"( sync block index ).這些成員由CLR共同管理對象.這些額外成員的字節數會計入對象大小.

  b.它從託管中分配指定類型要求的字節數,從而分配對象的內存,分配全部字節都設爲零.

  c.初始化"類型對象指針"和"同步化索引塊"

  d.調用類型的實例構造器.

注:引用類型有除了實例字段開銷以外,還包括兩個字段的開銷,即"同步化索引塊"和"類型對象指針".

 

 5.類型轉換 ( 看父不看子 )

  CLR最重要的特性就是類型安全性.在運行時,CLR老是知道一個對象是什麼類型.調用GetType方法,老是知道一個對象確切的類型是什麼.因爲這個方法是非虛方法(不能重寫覆蓋),因此一個類型不能假裝成另外一個類型.這句話很好理解,一個Employee類不能重寫GetType方法,因此不能返回一個其餘類型,好比SuperHero類型.

  C#不要求任何特殊語法便可將一個對象轉化爲它的任何基類型,由於基類型轉換被認爲是一種安全的隱式轉換.然而,將對象轉化爲它的某個派生類型時,C#要求只能進行顯式轉換,由於這樣的轉換可能在運行時失敗.

  注:聲明方法參數類型的最好方法是將參數類型指定,而不是Object,這避免了運行時錯誤,將錯誤提前到編譯時.

 

6.使用C#的 is 和 as 操做符來轉型

  使用 is 檢查一個對象是否兼容於指定的類型,並返回一個 boolean 值: true 或 false . ( is 永遠也不會拋出異常 ).

  若是對象的引用是 null , is 操做符老是返回 false ,由於沒有可供檢查的對象.

  is 操做符的使用:

1 if( o is Employee )
2 {
3     Employee e = (Employee) o;
4     ...
5 }

  在上面這段代碼中,CLR實際上會檢查兩次對象的類型. is 操做符首先覈實 o 是否兼容於 Employee 類型. 若是是,那麼在 if 語句內部執行轉型時,CLR再次覈實 o 是否引用一個Employee.這無疑形成了性能的損失.

  由於CLR必須判斷 變量o 引用的實際類型,而後CLR必須遍歷繼承層次結構,用 o 的每一個基類型去核對每一個指定的類型 Employee.

  因此,C#提供了另外一個操做符 as ,目的是簡化這段代碼操做 ,並提高其性能 .

1 Employee e = o as Employee;
2 if( null != e )
3 {
4     ...
5 }

  在這段代碼中,CLR覈實 o 是否兼容 Employee 類型 ;若是是,則 as 會返回對同一個對象的非 null 引用.若是 o 不兼容 Employee 類型, as 操做符會返回 null .

  檢查是否爲 null 比校驗一個對象的類型要效率的多.

  一樣, as 操做符也不會拋出異常.

  

7.命名空間和程序集

  命名空間用於邏輯性分組;

    CLR不知道命名空間的任何事,訪問一個類型時,CLR須要知道類型的完整名稱以及該類型具體定義在哪一個程序集中.

  建立命名空間別名:

 1 using Microsoft;            //嘗試添加"Microsoft."前綴
 2 using Wintellect;            //嘗試添加"Wintellect."前綴
 3 
 4 //將WintellectWidget符號定義成Wintellect.Widget的別名
 5 using WintellectWidget = Wintellect.Widget;
 6 
 7 public sealed class Program
 8 {
 9     public static void main()
10     {
11         //使用別名建立對象
12         WintellectWidget w = new WintellectWidget();
13     }
14 }
命名空間別名
 1 namespace CompanyName
 2 {
 3     public sealed class A {                        //TypeOf : Company.A
 4         ...
 5     }
 6 
 7     namespace X{
 8         public sealed class B { ... }            //TypeOf : CompanyName.X.B
 9     }
10 }
命名空間規則
相關文章
相關標籤/搜索