2013-04-04 9 views
6

Tôi có hai lớpSử dụng từ khóa mới trong C#

class A 
{ 
    public virtual void Metod1() 
    { 
     Console.WriteLine("A.Method1"); 
    } 
} 

class B : A 
{ 
    public new void Metod1() 
    { 
     Console.WriteLine("B.Method1"); 
    } 
} 

Sau đó, tôi viết một số mã mà tuyên bố trường hợp của các lớp này, và gọi các phương thức của họ

 static void Main(string[] args) 
    { 
     A a = new B(); 
     a.Metod1(); 
     B b = new B(); 
     b.Metod1(); 
     Console.ReadKey(); 
    } 

tôi đã cho sau kết quả:

A.Method1 
B.Method1 

Nhưng khi tôi xóa từ khóa mới từ phương thức chữ ký 1 của lớp B và chạy Phương thức chính, tôi nhận được kết quả tương tự. Câu hỏi: Từ khóa mới có phải là chữ ký của các phương thức chỉ để dễ đọc hơn không?

Chỉnh sửa: Có trường hợp nào chúng tôi không thể thực hiện mà không có từ khóa mới không?

+0

bạn phải sử dụng ghi đè lên hoặc mới trong lớp B bacause nếu không nó ẩn phương pháp phần tử cha của .. mặc định là mới vì vậy nếu bạn sẽ không đặt mới nó mang lại cho bạn không lỗi và chạy tốt .. –

+0

Lưu ý phụ: Cân nhắc "gây nhầm lẫn cho người đọc và người dùng mã" để sử dụng chính "mới" trong ngữ cảnh như vậy. Có những trường hợp khi sử dụng nó có thể cải thiện khả năng đọc (nghĩa là cần phải lấy được lớp cho một số lớp cơ sở không thân thiện), nhưng trong hầu hết các trường hợp, nó chỉ khó hiểu hơn khi phương thức của lớp cơ sở sẽ được gọi và khi có nguồn gốc. –

Trả lời

3

Có, bạn chính xác, nó là để dễ đọc hơn trong tình huống này.

Nhưng hãy kiểm tra cẩn thận bạn nên có cảnh báo không sử dụng mới khi ẩn phương thức cơ sở.

Bạn có thể đọc thêm ở đây: http://msdn.microsoft.com/en-us/library/vstudio/435f1dw2.aspx

+0

Bạn đã viết nó là để dễ đọc hơn trong tình huống này.Nhưng có những tình huống mà chúng tôi không thể làm mà không có từ khóa mới – cosset

+0

@cosset Có, khi nó không được sử dụng làm công cụ sửa đổi, Tức là: Class1 C = new Class1() hoặc khi bạn đặt để coi cảnh báo là lỗi. –

+0

Có những tình huống mà chúng tôi không thể thực hiện mà không có từ khóa mới trong chữ ký của phương thức, trường – cosset

6

Knowing When to Use Override and New Keywords (C# Programming Guide)

Trong C#, một phương pháp trong một lớp học có nguồn gốc có thể có cùng tên với một phương pháp trong lớp cơ sở. Bạn có thể chỉ định cách các phương thức tương tác bằng cách sử dụng từ khóa mới và ghi đè. Công cụ sửa đổi ghi đè mở rộng phương thức lớp cơ sở , và công cụ sửa đổi mới ẩn nó.

cũng

Bằng cách sử dụng mới, bạn đang khẳng định rằng bạn nhận thức được rằng các thành viên rằng nó sẽ thay đổi giấu một thành viên được thừa kế từ cơ sở lớp.

+0

có lớp cơ sở vẫn cần 'virtual' trong phương thức cho' new' trong bắt nguồn có bất kỳ ảnh hưởng nào không? Trong các thử nghiệm của tôi, có 'mới' trên một lớp dẫn xuất có cùng một hành vi đơn giản là không có' override' - tôi đang thiếu gì? Có nghĩa là gì bởi 'giấu nó'? – mmcrae

7

Các mới từ khóa để cho đầu đọc mã lưu ý rằng phương pháp này sẽ ẩn các phương pháp có cùng tên trong cơ sở của nó. Ngay cả khi bạn ommited nó, trình biên dịch sẽ đối xử với nó trong cùng một cách, nhưng cảnh báo bạn về điều đó.

Vì bạn tuyên bố phương pháp như ảo, bạn sẽ nhận được cảnh báo này khi bạn biên dịch:

'B.Metod1()' giấu được thừa hưởng thành viên 'A.Metod1()'. Để làm cho thành viên hiện tại ghi đè việc triển khai đó, hãy thêm từ khóa ghi đè. Nếu không, hãy thêm từ khóa mới.

Tuy nhiên, nếu bạn thay đổi tờ khai bằng cách loại bỏ ảo như:

  • Tuyên bố mà không ảo trong A

    class A { 
        public void Metod1() { 
         Console.WriteLine("A.Method1"); 
        } 
    } 
    
    class B: A { 
        public void Metod1() { 
         Console.WriteLine("B.Method1"); 
        } 
    } 
    

sẽ vẫn biên dịch, nhưng thông điệp cảnh báo sẽ là:

'B.Metod1()' ẩn thành viên được thừa kế 'A.Metod1()'.Sử dụng từ khóa mới nếu ẩn được dự định là.

Trong cả hai cách như trên, sau đây:

  • mã kiểm tra

    var b=new B(); 
    b.Metod1(); 
    (b as A).Metod1(); 
    

chí đầu ra:

 
B.Method1 
A.Method1 

Nhưng, nếu bạn khai báo như người theo dõi g:

  • Tuyên bố với override trong B

    class A { 
        public virtual void Metod1() { 
         Console.WriteLine("A.Method1"); 
        } 
    } 
    
    class B: A { 
        public override void Metod1() { 
         Console.WriteLine("B.Method1"); 
        } 
    } 
    

Sau đó đầu ra sẽ là:

 
B.Method1 
B.Method1 

Đó là bởi vì Method1 của lớp cơ sở không chỉ là bị ẩn nhưng ghi đè bởi lớp dẫn xuất.

Một trường hợp mà bạn không thể chỉ cần sử dụng mới là nếu Method1 là bản tóm tắt phương pháp trong một lớp trừu tượng:

  • Mã mà phải sử dụng override trong các lớp thừa

    abstract class A { 
        public abstract void Metod1(); 
    } 
    
    class B: A { 
        public override void Metod1() { // use `new` instead of `override` would not compile 
         Console.WriteLine("B.Method1"); 
        } 
    } 
    

Trong trường hợp này, bạn không thể chỉ sử dụng mới, vì A yêu cầu các lớp dẫn xuất để ghi đè Method1.

+0

Đó là ok, nhưng câu hỏi: Là từ khóa mới trong chữ ký của phương pháp chỉ cho dễ đọc hơn và có trường hợp chúng ta không thể làm mà không có một từ khóa mới – cosset

+0

do đó nó không thực sự thay đổi bất kỳ hành vi - nó chỉ là vì lợi ích của? – mmcrae