①做運算符
用於創建對象和調用構造函數,小栗子a如下:
Class1 obj = new Class1();
創建匿名類型的實例,小栗子b如下:
var query = from cust in customers select new {Name = cust.Name, Address = cust.PrimaryAddress};
用於調用值類型的默認構造函數,小栗子c如下: 其中 i 初始化為 0,它是 int 類型的默認值。該語句的效果等同於:int i=0;
int i = new int();
為結構聲明默認的構造函數是錯誤的,因為每一個值類型都隱式具有一個公共的默認構造函數。可以在結構類型上聲明參數化構造函數以設置其初始值,但是,只有在需要默認值之外的值時才必須這樣做。
值類型對象(例如結構)是在堆棧上創建的,而引用類型對象(例如類)是在堆上創建的。兩種類型的對象都是自動銷毀的,但是,基於值類型的對象是在超出范圍時銷毀,而基於引用類型的對象則是在對該對象的最后一個引用被移除之后在某個不確定的時間銷毀。對於占用固定資源(例如大量內存、文件句柄或網絡連接)的引用類型,有時需要使用確定性終止以確保對象被盡快銷毀。new運算符不可以重載.
②做修飾符,用於向基類成員隱藏繼承成員
作為修飾符,基本的規則可以總結為:實現派生類中隱藏方法,則基類方法必須定義為virtual;new作為修飾符,實現隱藏基類成員時,不可和 override共存,原因是這兩者語義相斥:new用於實現創建一個新成員,同時隱藏基類的同名成員;而override用於實現對基類成員的擴展。
小栗子b如下:
class Number { public static int i = 123; public void ShowInfo() { Console.WriteLine("base class---"); } public virtual void ShowNumber() { Console.WriteLine(i.ToString()); } } class IntNumber : Number { new public static int i = 456; public new virtual void ShowInfo() { Console.WriteLine("Derived class---"); } public override void ShowNumber() { Console.WriteLine("Base number is {0}", Number.i.ToString()); Console.WriteLine("New number is {0}", i.ToString()); } } static void Main(string[] args) { Number num = new Number(); num.ShowNumber(); //123 IntNumber intNum = new IntNumber(); intNum.ShowNumber(); //123 456 Number number = new IntNumber(); //究竟調用了誰? number.ShowInfo(); //base class--- //究竟調用了誰? number.ShowNumber(); //派生類里面重寫了ShowNumber(), 所以輸出的是: 123 456 Console.ReadKey(); }
運算結果:
③作為約束
new 約束指定泛型類聲明中的任何類型參數都必須有公共的無參數構造函數。如果要使用 new 約束,則該類型不能為抽象類型。當與其他約束一起使用時,new() 約束必須最后指定.