使用屬性而不是可訪問的數據成員:
類型的某些成員確實非常適合作爲數據,例如某個客戶的名稱,某個點的x,y座標或一年度的收入等。而屬性則讓你可以創建出類似於數據訪問,但實際上卻是方法調用的接口,自然也可以享受到方法調用的所有好處。
實例:
Public class Customer
{
private string name;
public string Name
{
get{ return name;}
set
{
if(string.IsNullOrEmpty(value))
throw new ArgumentException(
“Name cannot be blank”,”Name”);
name=value;
}
}
}
客戶對象不應該有空白的名稱。若你使用了公有屬性來封裝Name,那麼只要修改一處即可。
合理使用運行時常量和編譯期常量:
C#有兩種類型的常量:運行時常量(readonly)和編譯期常量(const)。二者有着截然不同的行爲,使用不當將會帶來性能上或正確性上的問題。編譯期常量比運行時常量速度上略微快一些,但是卻沒有運行時常量那麼靈活。
編譯期常量與運行時常量行爲的不同之處在於對它們的訪問方式不同。編譯期常量的值是在目標代碼中進行替換的。
Public const int Millennium=2000;
If(myDateTime.Year==Millennium)
等同於
If(myDateTime.Year==2000)
假如我們在一個名爲Infrastructure的程序集中分別定義了一個const字段和一個readonly字段:
public class UseFulValues
{
public static readonly int StartValue=5;
public const int EndValue=10;
}
在另一程序集中,我們使用了這兩個值:
For(int i=UsefulValues.StartValue; i<UseFulValues.EndValue;i++)
Console.WriteLine(“value is {0}”,i);
執行該程序,輸出如下:
Value is 5
Value is 6
……
Value is 9
過了一段時間,我們更新了Infrastructure程序集,做出瞭如下修改:
Public class UsefulValues
{
public static readonly int StartValue=105;
Public const int EndValue=120;
}
隨後在分發Infrastructure程序集時,並沒有重新編譯整個應用程序的所有程序集。我們期待的是如下的輸出:
Value is 105
Value is 106
……
Value is 119
請思考:但實際上,你卻看不到任何輸出。因爲現在那個循環語句將使用105作爲它的起始值,使用10作爲它的結束條件。
推薦使用is或as操作符:
(1)我們可以使用is語句來避免拋出異常或轉換。
(2)相對於強制類型轉換來說,as更加安全,也更加高效。
Object o=factory.GetObject();
MyType t=o as MyType;
If(t !=null){}
Else{}
或者也可以這樣:
Object o =Factory.GetObject();
Try
{
MyType t;
t=(MyType)o;
}
Catch(InvalidCaObject o=factory.GetObject();
stException){}
顯然第一種做法更加簡單易讀。其中並沒有try/catch語句,因此也避免了其帶來的開銷。
Object o = factory.GetValue();
Int i=0;
If(o is int)
i=(int)o;
請思考:若o是其他的某個可以轉換成int的類型,例如double,那麼is操作符將會返回false,若參數爲null,那麼is操作符總會返回false.
使用Conditional特性:
假如有一方法CheckState()當它在應用了Conditional特性之後,c#編譯器只有在檢測到定義了DEBUG環境變量時纔會對CheckState()方法進行調用。Conditional特性不會影響對CheckState()方法的編譯,它只會影響對該方法的調用。
[Conditional(“DEBUG”)]
Private void CheckState(){}
Public string LastName
{
get{CheckState();return lastName;}
set{CheckState();lastName=value;}
}
如果定義了DEBUG符號,你會得到如下代碼:
Public string LastName
{
get{CheckState();return lastName;}
set{CheckState();lastName=value;}
}
如果沒有定義,會得到這樣的代碼:
Public string LastName
{
get{return lastName;}
set{lastName=value;}
}
爲類型提供ToString()方法:
System.Object.ToString()是.NET環境中最常用的方法之一。你應該爲類型的所有使用者提供一個合理的ToString版本,否則使用者就不得不用你的類型的一些屬性來自行構造出一個人類可讀的表示。類型的字符串表示可用來在各種情況下向用戶輕鬆顯示對象的相關信息。
Public class Customer
{
public string Name{get;set;}
public string ContactPhone{get;set;}
public override string ToString(){return Name;}
}
繼承自Object類的ToString()方法將直接返回一個“Customer”字符串。這個字符串實在沒有什麼用處。對於Customer類來說,返回其名稱是個不錯的選擇:
Public override string ToString()
{return Name;}
C# 中的const 和Java中的final的區別:
最近正在學習安卓開發,發現java中有個final修飾符,乍一看好像C#中的const,所以在一段時間裏我認爲兩者是相同的作用,無非是變量初始化後不能更改,即只能在定義時或者構造函數中賦值。後來我看到final居然可以用static修飾就感覺到有些不對頭,因爲C#中的const是不能再用static修飾的,下面將爲大家詳細分析:
1.修飾變量
準確的說C#中的const 等價於 Java中的static final,也就是說,Java中final不具有static的功能。而C#中的const具有static的功能。因此在C#中 public const string 等將於java中的 public static final string。
2.修飾類和方法
此時Java中的final類似C#中的sealed,就是說,final修飾的類不能被繼承,final修飾的方法不能被覆蓋。
而C#中的const不能修飾類和方法。