2009-03-19 45 views
21

Dziś znalazłem coś w starym kodzie. Ma "statyczną nową" dla jednej funkcji. To wygląda tak.Jaki jest sens modyfikatora "statycznego nowego" dla funkcji?

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

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

ja nie rozumiem statyczną nowego modyfikator dla metody w klasie BarCzy. W języku C# metoda statyczna może być wywoływana tylko z nazwą klasy zamiast nazwą obiektu. Tak więc, nie sądzę, by istniała jakakolwiek różnica między posiadaniem "nowego" a nie.

Ogólnie, jeśli jakaś składnia nie jest konieczna, C# po prostu traktuj to jako błąd. Ktoś ma pojęcie o tym, dlaczego C# pozwala na taką składnię?

Odpowiedz

37

Jeśli usuniesz nowy z kodu otrzymasz:

ostrzeżenie CS0108: 'Bar.Do()' ukrywa odziedziczony element 'Foo.Do()'. Użyj nowego słowa kluczowego, jeśli chowanie było zamierzone.

C# kompilator tylko ostrzega, że ​​może robić coś, czego nie zamierza i prosi o włożenie nowy słowo kluczowe, aby potwierdzić, że wiesz co robisz. Oprócz wyłączenia ostrzeżenia, nie ma innych efektów.

+12

Warto zauważyć, że to jedyne, co powstrzymuje ostrzeżenie. Żadnych innych efektów. –

+0

Dobra uwaga. Dodałem to do anwer. –

+4

a to tylko pomija ostrzeżenie, robi to wyraźnie (w celu uniknięcia pomyłki), sprawdź moją odpowiedź – eglasius

7

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

Twój przykład, aby było jasne, powinny być

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

W powyższym przykładzie pasek drugiej klasy nie dziedziczy po Foo. To wydaje się literówka, ponieważ nie ma sensu, aby było inaczej.

Przyjmując, że jest to literówka, "nowy" modyfikator jawnie ukrywa wersję klasy podstawowej funkcji Do(). Oznacza to, że pochodna wersja metody Do() skutecznie zastępuje wersję klasy podstawowej.

Posługiwanie się "nowym" dokumentuje tutaj fakt, że metoda odziedziczona ma zastąpić wersję klasy podstawowej Do().

Aby uzyskać więcej informacji, zobacz new Modifier (C#)

+0

Oto zaktualizowana dokumentacja [nowego modyfikatora] (https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/new-modifier). – zodo

10

Dotyczy to tylko dla połączeń zewnętrznych. Pamiętaj, że możesz zadzwonić do statycznej metody klasy bazowej, więc coś w tym jest ważny:

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

Dlatego ostrzegawczy informuje umieścić nowy, chcesz uniknąć nieporozumień, gdy robi to:

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"); } 
}