一.全部類型都是從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 }
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 }