1. 程式人生 > >C#中New關鍵字的三種用法

C#中New關鍵字的三種用法

三種用法如下:

  在 C# 中,new 關鍵字可用作運算子、修飾符或約束。

  1)new 運算子:用於建立物件和呼叫建構函式。這種大家都比較熟悉,沒什麼好說的了。

  2)new 修飾符:在用作修飾符時,new 關鍵字可以顯式隱藏從基類繼承的成員。

  3)new 約束:用於在泛型宣告中約束可能用作型別引數的引數的型別。

  關於第二種用法看下例:

  using System;

  namespace ConsoleApplication1
{
    public class BaseA

  {
        public int x = 1;
        public void Invoke()
        {
            Console.WriteLine(x.ToString());
        }
        public int TrueValue
        {
            get { return x; }

  set { x = value; }
        }
    }

  public class DerivedB : BaseA
    {
        new public int x = 2;
        new public void Invoke()
        {
            Console.WriteLine(x.ToString());
        }
        new public int TrueValue
        {
            get { return x; }

  set { x = value; }
        }
    } 
    class Test
    {
        static void Main(string[] args)
        {

  DerivedB b = new DerivedB();

  b.Invoke();//呼叫DerivedB的Invoke方法,輸出:2

  Console.WriteLine(b.x.ToString());//輸出DerivedB的成員x值:2

  BaseA a = b;

  a.Invoke();//呼叫BaseA的Invoke方法,輸出:1

  a.TrueValue = 3;//呼叫BaseA的屬性TrueValue,修改BaseA的成員x的值

  Console.WriteLine(a.x.ToString());//輸出BaseA的成員x的值:3

  Console.WriteLine(b.TrueValue.ToString());//輸出DerivedB的成員x的值,仍然是:1

  //可見,要想訪問被隱藏的基類的成員變數、屬性或方法,辦法就是將子類造型為父類,然

  //後通過基類訪問被隱藏的成員變數、屬性或方法。
        }
     }
}

  new約束指定泛型類宣告中的任何型別引數都必須具有公共的無引數建構函式.請看下例:

using System;
using System.Collections.Generic;

  namespace ConsoleApplication2
{
    public class Employee
    {
        private string name;
        private int id;
        public Employee()

  {
            name = "Temp";

  id = 0;
        }
        public Employee(string s, int i)
        {
            name = s;

  id = i;
        }
        public string Name
       {

  get { return name; }

  set { name = value; }
        }

  public int ID
        {
            get { return id; }
  
            set { id = value; }
        }
    }

  class ItemFactory<T> where T : new()
    {
        public T GetNewItem()

  {
            return new T();
        }
   }
    public class Test
    {
        public static void Main()
        {
            ItemFactory<Employee> EmployeeFactory = new ItemFactory<Employee>();

  ////此處編譯器會檢查Employee是否具有公有的無參建構函式。

  //若沒有則會有The Employee must have a public parameterless constructor 錯誤。

  Console.WriteLine("{0}'ID is {1}.", EmployeeFactory.GetNewItem().Name, EmployeeFactory.GetNewItem().ID);
        }
    }
}

  見MSDN上關於New的解釋

  new 修飾符(C# 參考)

  在用作修飾符時,new 關鍵字可以顯式隱藏從基類繼承的成員。隱藏繼承的成員時,該成員的派生版本將替換基類版本。雖然可以在不使用new 修飾符的情況下隱藏成員,但會生成警告。 如果使用 new 顯式隱藏成員,則會取消此警告,並記錄要替換為派生版本這一事實。

  若要隱藏繼承的成員,請使用相同名稱在派生類中宣告該成員,並使用new 修飾符修飾該成員。例如:

public class BaseC
{
    public int x;
    public void Invoke() { }
}
public class DerivedC : BaseC
{
    new public void Invoke() { }
}

  在此示例中,DerivedC.Invoke 隱藏了BaseC.Invoke。欄位x 不受影響,因為它沒有被類似名稱的欄位隱藏。

  通過繼承隱藏名稱採用下列形式之一:

  引入類或結構中的常數、指定、屬性或型別隱藏具有相同名稱的所有基類成員。

  引入類或結構中的方法隱藏基類中具有相同名稱的屬性、欄位和型別。同時也隱藏具有相同簽名的所有基類方法。

  引入類或結構中的索引器將隱藏具有相同名稱的所有基類索引器。

  對同一成員同時使用 new 和 override 是錯誤的做法,因為這兩個修飾符的含義互斥。new 修飾符會用同樣的名稱建立一個新成員並使原始成員變為隱藏的。override 修飾符會擴充套件繼承成員的實現。

  在不隱藏繼承成員的宣告中使用new 修飾符將會生成警告。

  示例

  在該例中,基類 BaseC 和派生類 DerivedC 使用相同的欄位名 x,從而隱藏了繼承欄位的值。 該示例演示了 new 修飾符的用法。 另外還演示瞭如何使用完全限定名訪問基類的隱藏成員。

  public class BaseC
{
    public static int x = 55;
    public static int y = 22;
}

  public class DerivedC : BaseC
{
    // Hide field 'x'.
    new public static int x = 100;

  static void Main()
    {
        // Display the new value of x:
        Console.WriteLine(x);

  // Display the hidden value of x:
        Console.WriteLine(BaseC.x);

  // Display the unhidden member y:
        Console.WriteLine(y);
    }
}
/*
Output:
100
55
22
*/

  在此示例中,巢狀類隱藏了基類中同名的類。此示例演示瞭如何使用new 修飾符來消除警告訊息,以及如何使用完全限定名來訪問隱藏的類成員。

  public class BaseC 
{
    public class NestedC 
    {
        public int x = 200;
        public int y;
    }
}

  public class DerivedC : BaseC { // Nested type hiding the base type members.
    new public class NestedC   
    {
        public int x = 100;
        public int y; 
        public int z;
    }

  static void Main() 
    {
        // Creating an object from the overlapping class:
        NestedC c1  = new NestedC();

  // Creating an object from the hidden class:
        BaseC.NestedC c2 = new BaseC.NestedC();

  Console.WriteLine(c1.x);
        Console.WriteLine(c2.x);   
    }
}
/*
Output:
100
200
*/

  如果移除new 修飾符,該程式仍可編譯和執行,但您會收到以下警告:

The keyword new is required on 'MyDerivedC.x' because it hides inherited member 'MyBaseC.x'.