轉自MSDN:https://msdn.microsoft.com/zh-cn/library/435f1dw2.aspx
new隱藏基類成員
在用作修飾符時,new關鍵字可以顯式的隱藏從基類繼承的成員。隱藏繼承的成員時,該成員的派生版本將替換基類版本。雖然可以不使用new修飾符的情況下隱藏成員,但會生成警告。如果使用new顯示隱藏成員,則會取消此警告,並記錄要替換為派生版本這一事實。
若要隱藏繼承的成員,請使用相同名稱在派生類中聲明該成員,並使用new修飾符修飾該成員。例如:
1 public class BaseC 2 { 3 public int x; 4 public void Invoke() { } 5 } 6 public class DerivedC : BaseC 7 { 8 new public void Invoke() { } 9 }
在此示例中,DerivedC.Invoke隱藏了BaseC.Invoke。字段x不受影響,因為它沒有被類似名稱的字段隱藏。
通過繼承隱藏名稱采用下列形式之一:
- 引入類或結構中的常數、指定、屬性或類型隱藏具有相同名稱的所有基類成員。
- 引入類或結構中的方法隱藏基類中具有相同名稱的屬性、字段和類型。同時也隱藏具有相同簽名的所有基類方法。
- 引入雷火結構中的索引器將隱藏具有相同名稱的所有基類索引器。
對同一成員同時使用new和override是錯誤的做法,因為這兩個修飾符的含義互斥。new修飾符會用同樣的名稱創建一個新成員並使原始成員變為隱藏的。override修飾符會擴展繼承成員的實現。
在不隱藏繼承成員的聲明中使用new修飾符將會生成警告。
示例
在該例中,基類BaseC和派生類DerivedC使用相同的字段名x,從而隱藏了繼承字段的值。該實例演示了new修飾符的用法。另外還演示了如何使用完全限定名訪問基類的隱藏成員。
1 public class BaseC 2 { 3 public static int x = 55; 4 public static int y = 22; 5 } 6
7 public class DerivedC : BaseC 8 { 9 // Hide field 'x'.
10 new public static int x = 100; 11
12 static void Main() 13 { 14 // Display the new value of x:
15 Console.WriteLine(x); 16
17 // Display the hidden value of x:
18 Console.WriteLine(BaseC.x); 19
20 // Display the unhidden member y:
21 Console.WriteLine(y); 22 } 23 } 24 /*
25 Output: 26 100 27 55 28 22 29 */
在此示例中,嵌套類隱藏了基類中同名的類。此示例演示了如何使用new修飾符來消除警告消息,以及如何使用完全限定名來訪問隱藏的類成員。
1 public class BaseC 2 { 3 public class NestedC 4 { 5 public int x = 200; 6 public int y; 7 } 8 } 9
10 public class DerivedC : BaseC 11 { 12 // Nested type hiding the base type members.
13 new public class NestedC 14 { 15 public int x = 100; 16 public int y; 17 public int z; 18 } 19
20 static void Main() 21 { 22 // Creating an object from the overlapping class:
23 NestedC c1 = new NestedC(); 24
25 // Creating an object from the hidden class:
26 BaseC.NestedC c2 = new BaseC.NestedC(); 27
28 Console.WriteLine(c1.x); 29 Console.WriteLine(c2.x); 30 } 31 } 32 /*
33 Output: 34 100 35 200 36 */
如果移除new修飾符,該程序仍可編譯和運行,但您會收到以下警告:
The keyword new is required on 'MyDerivedC.x' because it hides inherited member 'MyBaseC.x'
new約束
當泛型類創建類型的新實例,請將 new 約束應用於類型參數,如下面的示例所示:
1 class ItemFactory<T> where T : new() 2 { 3 public T GetNewItem() 4 { 5 return new T(); 6 } 7 }