2009-03-19 16 views
21

Hôm nay, tôi đã tìm thấy thứ gì đó trong mã cũ. Nó có "tĩnh mới" cho một chức năng. Nó trông như thế nàyĐiểm sửa đổi "tĩnh mới" cho một hàm là gì?

class Foo 
{ 
    public static void Do() 
    { 
     Console.WriteLine("Foo.Do"); 
    } 
} 

class Bar: Foo 
{ 
    public static new void Do() 
    { 
     Console.WriteLine("Bar.Do"); 
    } 
} 

Tôi không hiểu được tĩnh mới modifier cho phương pháp Do trong lớp Bar. Trong C#, phương thức tĩnh chỉ có thể được gọi với tên lớp thay vì tên đối tượng. Vì vậy, tôi không nghĩ rằng có bất kỳ sự khác biệt giữa việc có "mới" và không.

Nói chung, nếu một số cú pháp là không cần thiết, C# chỉ coi đó là lỗi. Bất kỳ ai cũng có ý tưởng về lý do tại sao C# cho phép cú pháp như vậy?

Trả lời

37

Nếu bạn loại bỏ các mới từ mã của bạn, bạn nhận được:

cảnh báo CS0108: 'Bar.Do()' ẩn thành viên được thừa kế 'Foo.Do()'. Sử dụng từ khóa mới nếu dự định ẩn.

CáC# biên dịch C chỉ cảnh báo bạn rằng bạn có thể làm điều gì đó bạn không có ý định và yêu cầu bạn chèn mới từ khóa để xác nhận rằng bạn biết những gì bạn đang làm. Bên cạnh việc ngăn chặn cảnh báo, nó không có tác dụng khác.

+12

Điều đáng chú ý là nó _only_ ngăn chặn cảnh báo. Không có hiệu ứng nào khác. –

+0

Điểm tốt. Tôi thêm nó vào anwer. –

+4

trong khi nó chỉ ngăn chặn các cảnh báo, nó làm cho ý định rõ ràng (để tránh bất kỳ sự nhầm lẫn), kiểm tra câu trả lời của tôi – eglasius

7

có một cái nhìn tại this

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 
*/ 

ví dụ của bạn, để làm cho nó rõ ràng, nên

public class Foo 
{ 
    public static void Do() {} 
} 
public class Bar :Foo 
{ 
    public new static void Do() {} 
} 
4

Trong ví dụ của bạn, thanh hạng hai dường như không thừa kế từ Foo. Điều này có vẻ là một lỗi đánh máy bởi vì nó không có ý nghĩa khác.

Giả sử nó là lỗi đánh máy, công cụ sửa đổi "mới" sẽ ẩn một cách rõ ràng phiên bản lớp cơ sở của hàm Do(). Điều này có nghĩa là phiên bản dẫn xuất của phương thức Do() thay thế hiệu quả phiên bản lớp cơ sở.

Sử dụng "mới" ở đây chứng minh rằng phương pháp được kế thừa được dự định là thay thế cho phiên bản lớp cơ sở là Do().

Để biết thêm thông tin, hãy xem new Modifier (C#)

+0

Đây là tài liệu cập nhật của [công cụ sửa đổi mới] (https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/new-modifier). – zodo

10

Chỉ áp dụng cho người gọi bên ngoài. Hãy nhớ rằng bạn có thể gọi một phương thức tĩnh của lớp cơ sở, vì vậy một cái gì đó như thế này là hợp lệ:

class Foo 
{ 
    public static void Do() { Console.WriteLine("Foo.Do"); } 
} 
class Bar : Foo // :Foo added 
{ 
    public static void Something() 
    { 
     Do(); 
    } 
} 

Đây là lý do tại sao các cảnh báo cho bạn biết để đặt mới, bạn muốn tránh bất kỳ sự nhầm lẫn khi làm điều này:

class Foo 
{ 
    public static void Do() { Console.WriteLine("Foo.Do"); } 
} 
class Bar : Foo // :Foo added 
{ 
    public static void Something() 
    { 
     Do(); 
    } 
    public static new void Do() { Console.WriteLine("Bar.Do"); } 
}