免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
C# 規(guī)范整理·語言要素

作者:天空的湛藍(lán)

鏈接:https://www.cnblogs.com/zhan520g/p/11014918.html

1、正確操作字符串

  • 拼接字符串一定要考慮使用StringBuilder ,默認(rèn)長度為16,實(shí)際看情況設(shè)置。

  • StringBuilder本質(zhì):是以非托管方式分配內(nèi)存。

  • 同時(shí)StringFormat方法內(nèi)部也是使用StringBuilder進(jìn)行字符串格式化。

2、使用默認(rèn)轉(zhuǎn)型方法

類型的轉(zhuǎn)換運(yùn)算符 :每個(gè)類型內(nèi)部都有一個(gè)方法(運(yùn)算符),分為隱式轉(zhuǎn)換和顯示轉(zhuǎn)換。

自己實(shí)現(xiàn)隱式轉(zhuǎn)換:

puclic static implicit operator Ip(string ip)
{
Ip iptemp=new Ip(ip);
return iptemp;
}
  1. 使用類型內(nèi)置的Parse、TryParse、 ToString、ToDouble、 ToDateTime

  2. 使用幫助類提供的方法:System.Convert類、 System.BitConverter類來進(jìn)行類型的轉(zhuǎn)換。

  3. 使用CLR支持的類型:父類和子類之間的轉(zhuǎn)換。

3、區(qū)別對待強(qiáng)制轉(zhuǎn)型與as和is

為了編譯更強(qiáng)壯的代碼,建議更常使用as和is

什么時(shí)候使用as

如果類型之間都上溯到了某個(gè)共同的基類,那么根據(jù)此基類進(jìn)行的轉(zhuǎn)型(即基類轉(zhuǎn)型為子類本身)應(yīng)該使用as。子類與子類之間的轉(zhuǎn)型,則應(yīng)該提供轉(zhuǎn)換操作符,以便進(jìn)行強(qiáng)制轉(zhuǎn)型。

as操作符永遠(yuǎn)不會拋出異常,如果類型不匹配(被轉(zhuǎn)換對象的運(yùn)行時(shí)類型既不是所轉(zhuǎn)換的目標(biāo)類型,也不是其派生類型),或者轉(zhuǎn)型的源對象為null,那么轉(zhuǎn)型之后的值也為null。

什么時(shí)候使用is

as操作符有一個(gè)問題,即它不能操作基元類型。如果涉及基元類型的算法,就需要通過is轉(zhuǎn)型前的類型來進(jìn)行判斷,以避免轉(zhuǎn)型失敗。

4、TryParse比Parse好

這個(gè)肯定好,不說了。安全

5、使用int?來確保值類型也可以為null

基元類型為什么需要為null?考慮兩個(gè)場景:

  • 數(shù)據(jù)庫支持整數(shù)可為空

  • 數(shù)據(jù)在傳輸過程中存在丟失問題,導(dǎo)致傳過來的值為null

寫法:int ? i=null;

語法T?是Nullable<T>的簡寫,兩者可以相互轉(zhuǎn)換。可以為null的類型表示其基礎(chǔ)值類型正常范圍內(nèi)的值再加上一個(gè)null值。例如,Nullable<Int32>,其值的范圍為-2 147 483 648~2 147 483 647,再加上一個(gè)null值。

?經(jīng)常和??配合使用,比如:

int?i=123;
int j=i??0;

6、區(qū)別readonly和const的使用方法

使用const的理由只有一個(gè),那就是效率。之所以說const變量的效率高,是因?yàn)榻?jīng)過編譯器編譯后,我們在代碼中引用const變量的地方會用const變量所對應(yīng)的實(shí)際值來代替。比如:const=100, const和100被使用的時(shí)候是等價(jià),const自帶static光圈。

const和readonly的本質(zhì)區(qū)別如下:

  • const是編譯期常量,readonly是運(yùn)行期常量

  • const只能修飾基元類型、枚舉類型或字符串類型,readonly沒有限制。

注意:在構(gòu)造方法內(nèi),可以多次對readonly賦值。即在初始化的時(shí)候。

7、將0值作為枚舉的默認(rèn)值

允許使用的枚舉類型有byte、sbyte、short、ushort、int、uint、long和ulong。應(yīng)該始終將0值作為枚舉類型的默認(rèn)值。不過,這樣做不是因?yàn)樵试S使用的枚舉類型在聲明時(shí)的默認(rèn)值是0值,而是有工程上的意義。

既然枚舉類型從0開始,這樣可以避免一個(gè)星期多出來一個(gè)0值。

8、避免給枚舉類型的元素提供顯式的值

不要給枚舉設(shè)定值。有時(shí)候有某些增加的需要,會為枚舉添加元素,在這個(gè)時(shí)候,就像我們?yōu)槊杜e增加元素ValueTemp一樣,極有可能會一不小心增加一個(gè)無效值。

9、習(xí)慣重載運(yùn)算符

比如:Salary familyIncome=mikeIncome+roseIncome; 閱讀一目了然。通過使用opera-tor關(guān)鍵字定義靜態(tài)成員函數(shù)來重載運(yùn)算符,讓開發(fā)人員可以像使用內(nèi)置基元類型一樣使用該類型。

10、創(chuàng)建對象時(shí)需要考慮是否實(shí)現(xiàn)比較器

有特殊需要比較的時(shí)候就考慮。集合排序比較通過linq 也可以解決。

11、區(qū)別對待==和Equals

無論是操作符“==”還是方法“Equals”,都傾向于表達(dá)這樣一個(gè)原則:

  • 對于值類型,如果類型的值相等,就應(yīng)該返回True。

  • 對于引用類型,如果類型指向同一個(gè)對象,則返回True。

注意 

  • 由于操作符“==”和“Equals”方法從語法實(shí)現(xiàn)上來說,都可以被重載為表示“值相等性”和“引用相等性”。所以,為了明確有一種方法肯定比較的是“引用相等性”,F(xiàn)CL中提供了Object.ReferenceEquals方法。該方法比較的是:兩個(gè)示例是否是同一個(gè)示例。

  • 對于string這樣一個(gè)特殊的引用類型,微軟覺得它的現(xiàn)實(shí)意義更接近于值類型,所以,在FCL中,string的比較被重載為針對“類型的值”的比較,而不是針對“引用本身”的比較。

12、重寫Equals時(shí)也要重寫GetHashCode

除非考慮到自定義類型會被用作基于散列的集合的鍵值;否則,不建議重寫Equals方法,因?yàn)檫@會帶來一系列的問題。

集合找到值的時(shí)候本質(zhì)上是先去 查找HashCode,然后才查找該對象來比較Equals

注意:重寫Equals方法的同時(shí),也應(yīng)該實(shí)現(xiàn)一個(gè)類型安全的接口IEquatable<T>,比如 :class Person:IEquatable

13、為類型輸出格式化字符串

有兩種方法可以為類型提供格式化的字符串輸出。

  • 一種是意識到類型會產(chǎn)生格式化字符串輸出,于是讓類型繼承接口IFormattable。這對類型來說,是一種主動(dòng)實(shí)現(xiàn)的方式,要求開發(fā)者可以預(yù)見類型在格式化方面的要求。

  • 更多的時(shí)候,類型的使用者需為類型自定義格式化器,這就是第二種方法,也是最靈活多變的方法,可以根據(jù)需求的變化為類型提供多個(gè)格式化器。

一個(gè)典型的格式化器應(yīng)該繼承接口IFormatProvider和ICustomFomatter

14、正確實(shí)現(xiàn)淺拷貝和深拷貝

淺拷貝 

將對象中的所有字段復(fù)制到新的對象(副本)中。其中,值類型字段的值被復(fù)制到副本中后,在副本中的修改不會影響到源對象對應(yīng)的值。而引用類型的字段被復(fù)制到副本中的是引用類型的引用,而不是引用的對象,在副本中對引用類型的字段值做修改會影響到源對象本身。

深拷貝 

同樣,將對象中的所有字段復(fù)制到新的對象中。不過,無論是對象的值類型字段,還是引用類型字段,都會被重新創(chuàng)建并賦值,對于副本的修改,不會影響到源對象本身。

無論是淺拷貝還是深拷貝,微軟都建議用類型繼承IClone-able接口的方式明確告訴調(diào)用者:該類型可以被拷貝。當(dāng)然,ICloneable接口只提供了一個(gè)聲明為Clone的方法,我們可以根據(jù)需求在Clone方法內(nèi)實(shí)現(xiàn)淺拷貝或深拷貝。

一個(gè)簡單的淺拷貝的實(shí)現(xiàn)代碼如下所示:

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類型是引用類型,但是由于該引用類型的特殊性(無論是實(shí)現(xiàn)還是語義),Object.MemberwiseClone方法仍舊為其創(chuàng)建了副本。也就是說,在淺拷貝過程,我們應(yīng)該將字符串看成是值類型。

一個(gè)簡單的深拷貝實(shí)現(xiàn)樣例如下(建議使用序列化的形式來進(jìn)行深拷貝)

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
}

同時(shí)實(shí)現(xiàn)深拷貝和淺拷貝

由于接口ICloneable只有一個(gè)模棱兩可的Clone方法,所以,如果要在一個(gè)類中同時(shí)實(shí)現(xiàn)深拷貝和淺拷貝,只能由我們自己實(shí)現(xiàn)兩個(gè)額外的方法,聲明為DeepClone和Shallow。Em-ployee的最終版本看起來應(yīng)該像如下的形式:

[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;
}}

15、利用dynamic來簡化反射實(shí)現(xiàn)

dynamic是Framework 4.0的新特性。dynamic的出現(xiàn)讓C#具有了弱語言類型的特性。編譯器在編譯的時(shí)候不再對類型進(jìn)行檢查,編譯器默認(rèn)dynamic對象支持開發(fā)者想要的任何特性。

比如,即使你對GetDynamicObject方法返回的對象一無所知,也可以像如下這樣進(jìn)行代碼的調(diào)用,編譯器不會報(bào)錯(cuò):

dynamic dynamicObject=GetDynamicObject();
Console.WriteLine(dynamicObject.Name);
Console.WriteLine(dynamicObject.SampleMethod());

當(dāng)然,如果運(yùn)行時(shí)dynamicObject不包含指定的這些特性(如上文中帶返回值的方法SampleMethod),運(yùn)行時(shí)程序會拋出一個(gè)RuntimeBinderException異常:“System.Dynamic.ExpandoObject”未包含“Sam-pleMethod”的定義。

var與dynamic有巨大的區(qū)別

  • var是編譯器的語法糖

  • dynamic是運(yùn)行時(shí)解析,在編譯期時(shí),編譯器不對其做任何檢查。

反射使用

  • 不使用dynamic方式

DynamicSample dynamicSample=new DynamicSample();
var addMethod=typeof(DynamicSample).GetMethod('Add');
int re=(int)addMethod.Invoke(dynamicSample,new object[] {1,2});
  • 使用dynamic方式

dynamic dynamicSample2=new DynamicSample();
int re2=dynamicSample2.Add(1,2);
//在使用dynamic后,代碼看上去更簡潔了,并且在可控的范圍內(nèi)減少了一次拆箱的機(jī)會。經(jīng)驗(yàn)證,頻繁使用的時(shí)候,消耗時(shí)間更少

建議:始終使用dynamic來簡化反射實(shí)現(xiàn)。

總結(jié)

在大部分應(yīng)用情況下,“效率”并沒有那么高的地位,靈活性更重要。在部分情況下,“靈活性”并沒有那么高的地位,效率最重要。


編號326,輸入編號直達(dá)本文

●輸入m獲取文章目錄

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報(bào)
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
C#程序編寫高質(zhì)量代碼改善的157個(gè)建議【13-15】[為類型輸出格式化字符串、實(shí)現(xiàn)淺拷貝和深拷貝、用dynamic來優(yōu)化反射]
C#編程總結(jié)(十四)dynamic
C++四種強(qiáng)制轉(zhuǎn)換
UC頭條:[C ]數(shù)據(jù)類型轉(zhuǎn)換
字符串以及內(nèi)存操作相關(guān)函數(shù)
strcpy、memcpy和memset之間的區(qū)別
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服