puclic static implicit operator Ip(string ip) { Ip iptemp=new Ip(ip); return iptemp; }
使用類型內置的Parse、TryParse、 ToString、ToDouble、 ToDateTime算法
使用CLR支持的類型:父類和子類之間的轉換。數據庫
爲了編譯更強壯的代碼,建議更常使用as和is安全
何時使用aside
何時使用is函數
這個確定好,不說了。安全ui
基元類型爲何須要爲null?考慮兩個場景:this
寫法: int?i=null;code
語法T?是Nullable<T>的簡寫,二者能夠相互轉換。能夠爲null的類型表示其基礎值類型正常範圍內的值再加上一個null值。例如,Nullable<Int32>,其值的範圍爲-2 147 483 648~2 147 483 647,再加上一個null值。orm
?常常和??配合使用,好比:對象
int?i=123; int j=i??0;
使用const的理由只有一個,那就是效率。之因此說const變量的效率高,是由於通過編譯器編譯後,咱們在代碼中引用const變量的地方會用const變量所對應的實際值來代替。好比: const=100, const和100被使用的時候是等價,const自帶static光圈。
const和readonly的本質區別以下:
容許使用的枚舉類型有byte、sbyte、short、ushort、int、uint、long和ulong。應該始終將0值做爲枚舉類型的默認值。不過,這樣作不是由於容許使用的枚舉類型在聲明時的默認值是0值,而是有工程上的意義。
既然枚舉類型從0開始,這樣能夠避免一個星期多出來一個0值。
不要給枚舉設定值。有時候有某些增長的須要,會爲枚舉添加元素,在這個時候,就像咱們爲枚舉增長元素ValueTemp同樣,極有可能會一不當心增長一個無效值。
好比:Salary familyIncome=mikeIncome+roseIncome; 閱讀一目瞭然。經過使用opera-tor關鍵字定義靜態成員函數來重載運算符,讓開發人員能夠像使用內置基元類型同樣使用該類型。
有特殊須要比較的時候就考慮。集合排序比較經過linq 也能夠解決。
不管是操做符「==」仍是方法「Equals」,都傾向於表達這樣一個原則:
對於引用類型,若是類型指向同一個對象,則返回True。
注意
注意
重寫Equals方法的同時,也應該實現一個類型安全的接口IEquatable<T>,好比 :class Person:IEquatable
有兩種方法能夠爲類型提供格式化的字符串輸出。
一個典型的格式化器應該繼承接口IFormatProvider和ICustomFomatter
淺拷貝
將對象中的全部字段複製到新的對象(副本)中。其中,值類型字段的值被複制到副本中後,在副本中的修改不會影響到源對象對應的值。而引用類型的字段被複制到副本中的是引用類型的引用,而不是引用的對象,在副本中對引用類型的字段值作修改會影響到源對象自己。
深拷貝
一樣,將對象中的全部字段複製到新的對象中。不過,不管是對象的值類型字段,仍是引用類型字段,都會被從新建立並賦值,對於副本的修改,不會影響到源對象自己。
不管是淺拷貝仍是深拷貝,微軟都建議用類型繼承IClone-able接口的方式明確告訴調用者:該類型能夠被拷貝。固然,ICloneable接口只提供了一個聲明爲Clone的方法,咱們能夠根據需求在Clone方法內實現淺拷貝或深拷貝。
class Employee:ICloneable { public string IDCode {get;set;} public int Age {get;set; } public Department Department{get;set;} #region ICloneable成員 public object Clone() { return this.MemberwiseClone(); } #endregion } class Department { public string Name {get;set;} public override string ToString() { return this.Name; } }
注意到Employee的IDCode屬性是string類型。理論上string類型是引用類型,可是因爲該引用類型的特殊性(不管是實現仍是語義),Object.MemberwiseClone方法仍舊爲其建立了副本。也就是說,在淺拷貝過程,咱們應該將字符串當作是值類型。
class Employee:ICloneable { public string IDCode{get;set;} public int Age{get;set;} public Department Department{get;set;} #region ICloneable成員 public object Clone() { using(Stream objectStream=new MemoryStream()) { IFormatter formatter=new BinaryFormatter(); formatter.Serialize(objectStream,this); objectStream.Seek(0,SeekOrigin.Begin); return formatter.Deserialize(objectStream)as Employee; } } #endregion}
同時實現深拷貝和淺拷貝
因爲接口ICloneable只有一個模棱兩可的Clone方法,因此,若是要在一個類中同時實現深拷貝和淺拷貝,只能由咱們本身實現兩個額外的方法,聲明爲DeepClone和Shallow。Em-ployee的最終版本看起來應該像以下的形式:
[Serializable] class Employee:ICloneable { public string IDCode{get;set;} public int Age{get;set;} public Department Department{get;set;} #region ICloneable成員 public object Clone() { return this.MemberwiseClone(); } #endregion public Employee DeepClone() { using(Stream objectStream=new MemoryStream()) { IFormatter formatter=new BinaryFormatter(); formatter.Serialize(objectStream,this); objectStream.Seek(0,SeekOrigin.Begin); return formatter.Deserialize(objectStream)as Employee; } } public Employee ShallowClone() { return Clone()as Employee; }}
dynamic是Framework 4.0的新特性。dynamic的出現讓C#具備了弱語言類型的特性。編譯器在編譯的時候再也不對類型進行檢查,編譯器默認dynamic對象支持開發者想要的任何特性。
好比,即便你對GetDynamicObject方法返回的對象一無所知,也能夠像以下這樣進行代碼的調用,編譯器不會報錯:
dynamic dynamicObject=GetDynamicObject(); Console.WriteLine(dynamicObject.Name); Console.WriteLine(dynamicObject.SampleMethod());
固然,若是運行時dynamicObject不包含指定的這些特性(如上文中帶返回值的方法SampleMethod),運行時程序會拋出一個RuntimeBinderException異常:「System.Dynamic.ExpandoObject」未包含「Sam-pleMethod」的定義。
var與dynamic有巨大的區別
反射使用
DynamicSample dynamicSample=new DynamicSample(); var addMethod=typeof(DynamicSample).GetMethod("Add"); int re=(int)addMethod.Invoke(dynamicSample,new object[] {1,2});
dynamic dynamicSample2=new DynamicSample(); int re2=dynamicSample2.Add(1,2); //在使用dynamic後,代碼看上去更簡潔了,而且在可控的範圍內減小了一次拆箱的機會。經驗證,頻繁使用的時候,消耗時間更少
建議:始終使用dynamic來簡化反射實現。
總結
在大部分應用狀況下,「效率」並無那麼高的地位,靈活性更重要。在部分狀況下,「靈活性」並無那麼高的地位,效率最重要。