2009-03-19 8 views
21

Heute habe ich etwas in Legacy-Code gefunden. Es hat "statisch neu" für eine Funktion. Es sieht aus wie das.Was ist der Modifikator "statisch neu" für eine Funktion?

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

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

Ich verstehe nicht, den statischen neuen Modifikator für die Do Methode in der Klasse Bar. In C# kann die statische Methode nur mit dem Klassennamen anstelle des Objektnamens aufgerufen werden. Also, ich denke nicht, dass es einen Unterschied zwischen dem "Neuen" und nicht dem Unterschied gibt.

Im Allgemeinen, wenn einige Syntax unnötig ist, C# nur behandeln es ist ein Fehler. Hat jemand eine Vorstellung davon, warum C# eine solche Syntax zulässt?

Antwort

37

, wenn Sie die neue aus dem Code erhalten Sie entfernen:

warning CS0108: 'Bar.Do()' verbirgt das geerbte Mitglied 'Foo.Do()'. Verwenden Sie das neue Schlüsselwort, wenn das Ausblenden beabsichtigt war.

Die C# Compiler warnt Sie nur, dass Sie etwas zu tun, werden Sie vielleicht nicht die Absicht haben, und fragt Sie nach dem neuen Schlüsselwort einzufügen, um zu bestätigen, dass Sie wissen, was Sie tun. Abgesehen davon, dass die Warnung unterdrückt wird, hat sie keine anderen Auswirkungen.

+12

Es ist erwähnenswert, dass es _only_ eine Warnung unterdrückt. Keine anderen Effekte. –

+0

Guter Punkt. Ich habe das dem Anwer hinzugefügt. –

+4

Während es nur die Warnung unterdrückt, macht es die Absicht explizit (um jede Verwirrung zu vermeiden), überprüfen Sie meine Antwort – eglasius

7

haben einen Blick auf 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 
*/ 

Ihr Beispiel deutlich zu machen, sollte

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

In Ihrem Beispiel scheint die zweite Klassenleiste nicht von Foo zu erben. Dies scheint ein Tippfehler zu sein, weil es sonst keinen Sinn ergibt.

Unter der Annahme, dass es sich um einen Tippfehler handelt, verbirgt der Modifikator "new" explizit die Basisklassenversion der Funktion Do(). Dies bedeutet, dass die abgeleitete Version der Do()-Methode die Basisklassenversion effektiv ersetzt.

Mit "neu" wird dokumentiert, dass die geerbte Methode als Ersatz für die Basisklassenversion Do() dient.

Weitere Informationen finden Sie new Modifier (C#)

+0

Hier ist die aktualisierte Dokumentation des [neuen Modifizierers] (https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/new-modifier). – zodo

10

, die nur für externe Anrufer gilt. Denken Sie daran, dass Sie eine statische Methode der Basisklasse aufrufen kann, so etwas wie dies gilt:

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

Aus diesem Grund ist die Warnung Ihnen sagt, die neue zu setzen, wollen Sie, um Verwechslungen zu vermeiden, wenn dies zu tun:

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