2009-03-19 9 views
21

Oggi ho trovato qualcosa nel codice legacy. Ha "statico nuovo" per una funzione. Sembra cosìQual è il punto del modificatore "new static" per una funzione?

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

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

Non capisco il statica nuovo modificatore per il metodo fare in classe Bar. In C#, il metodo statico può essere richiamato solo con il nome della classe anziché con il nome dell'oggetto. Quindi, non penso ci sia alcuna differenza tra avere il "nuovo" e non.

In genere, se una certa sintassi non è necessaria, C# tratta solo di un errore. Qualcuno ha qualche idea sul perché C# consente tale sintassi?

risposta

37

Se si rimuove il nuova dal codice che si ottiene:

avviso CS0108: 'Bar.Do()' nasconde il membro ereditato 'Foo.Do()'. Usa la nuova parola chiave se il nascondiglio era inteso.

Il compilatore C# solo si avverte che si potrebbe fare qualcosa che non si intendeva e chiede di inserire la nuova parola chiaveper confermare che si sa cosa si sta facendo. Oltre a sopprimere l'avvertimento, non ha altri effetti.

+12

Vale la pena notare che _ solo _ sopprime un avviso. Nessun altro effetto –

+0

Buon punto. L'ho aggiunto all'anwer. –

+4

mentre sopprime solo l'avviso, rende esplicita l'intenzione (per evitare qualsiasi confusione), controlla la mia risposta – eglasius

7

uno sguardo al 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 
*/ 

Il vostro esempio, per far capire, dovrebbe essere

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

Nel tuo esempio, la barra di seconda classe non sembra ereditare da Foo. Questo sembra essere un errore di battitura perché non ha senso altrimenti.

Supponendo che sia un errore di battitura, il "nuovo" modificatore nasconde esplicitamente la versione della classe base della funzione Do(). Ciò significa che la versione derivata del metodo Do() sostituisce in modo efficace la versione della classe base.

L'utilizzo di "nuovo" qui documenta il fatto che il metodo ereditato è destinato alla sostituzione della versione della classe base di Do().

Per ulteriori informazioni, vedere new Modifier (C#)

+0

Ecco la documentazione aggiornata del [nuovo modificatore] (https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/new-modifier). – zodo

10

che si applica solo per i chiamanti esterni. Ricordate che si può chiamare un metodo statico della classe base, in modo da qualcosa di simile è valido:

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

Questo è il motivo per cui l'avviso ti dice di mettere il nuovo, si vuole evitare qualsiasi confusione quando si fa questo:

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