2009-08-10 12 views
7

Rozważmy następujący kod:Jaki wpływ ma słowo kluczowe "nowe" w języku C# i dlaczego jest to tylko ostrzeżenie, gdy nie jest używane?

public abstract class Test1 
{ 
    public object Data { get; set; } 
} 

public abstract class Test2<T> : Test1 
{ 
    public T Data { get; set; } 
} 

To wygeneruje następujące ostrzeżenie:

skór 'Test2.Data dziedziczone członkowskiego 'Test1.Data'. Użyj nowego słowa kluczowego, jeśli chowanie było zamierzone.

Dlaczego jest to tylko ostrzeżenie i jaki wpływ będzie miało dodanie słowa kluczowego "nowe"?

Według moich testów nie mogę znaleźć żadnej różnicy po dodaniu słowa kluczowego "nowe".

Nie zrozumcie mnie źle, jestem za tym, że jestem bezpośredni, ale byłem ciekawy korzyści z dodania "nowego".

My tylko myśli o tym, co to może być to:

  • Lepsza ludzki czytelność
  • Niektóre oszczędności w czasie wykonywania, gdy kompilator nie jest w lewo, aby dowiedzieć się nieuniknione długiej drodze wokół

Odpowiedz

21

Jedynym skutkiem słowa kluczowego new jest usunięcie ostrzeżenia. Celem uzyskania ostrzeżenia, gdy nie jest używane słowo kluczowe new, jest zapobieganie przypadkowemu zacieniowaniu metody, gdy naprawdę chcesz ją przesłonić.

2

Włącz ostrzeżenia raportu jako błędy. To zmusi Cię do bliższego poznania sposobu użycia nowego i zastąpienia.

3

new służy do ukrycia metody lub właściwości klasy bazowej. Jest to nie jak nadpisanie: członek nie musi mieć tego samego podpisu co ukryty element członkowski klasy podstawowej i nie jest zaangażowany w polimorfizm.

Przykład:

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

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

class B : A 
{ 
    public override void Test() 
    { 
     Console.WriteLine("C.Test"); 
    } 
} 

public static void Main(string[] args) 
{ 
    A aa = new A(); 
    aa.Test(); // Prints "A.Test" 

    A ab = new B(); 
    ab.Test(); // Prints "A.Test" because B.Test doesn't overrides A.Test, it hides it 

    A ac = new C(); 
    ac.Test(); // Prints "C.Test" because C.Test overrides A.Test 

    B b = new B(); 
    b.Test(); // Prints "B.Test", because the actual type of b is known at compile to be B 
} 
+1

new nie robi nic (oprócz wyłączenia ostrzeżenia). Ukrywanie dzieje się przez pomijanie. –

+0

Tak, ale podając słowo kluczowe 'new', jawnie ukrywasz element. Chociaż w końcu nic nie zmienia, to dowodzi, że wiesz, co robisz, i przypadkowo nie zapomniałeś słowa kluczowego "override". –

+0

Nie, ukrywanie się też dzieje się bez nowego –

1

czy metoda pochodzi klasy powinny być traktowane jako nadpisanie metody bazowej klasy o tej samej nazwie często zależy od tego, czy autor metody pochodzi klasy był świadomy metody klasy podstawowej i powiązanej z nią umowy, i napisała metodę klasy pochodnej w celu wypełnienia tej umowy. W większości przypadków, gdy metoda klasy pochodnej ma taką samą nazwę i podpis jak metoda klasy bazowej, metoda klasy pochodnej byłaby przeznaczona do spełnienia umowy bazowej, ale jeśli autor wdrożonej klasy bazowej dodaje nazwę nie zdając sobie sprawy, że ta sama nazwa jest używana w jakimś innym celu w klasie pochodnej, nie można domniemywać, że autor metody klasy pochodnej napisał swoją metodę zgodności z umową dotyczącą metody bazowej, która nie istniała w tym czasie. .

Nie ma żadnych ogólnych środków, dzięki którym C# może stwierdzić, kiedy różne metody zostały dodane do klas, a zatem nie ma możliwości, aby kompilator wiedział, czy autor metody klasy pochodnej wiedział coś o istnieniu czegoś podobnego. nazwana metoda klasy bazowej , chyba że autor metody klasy pochodnej wyraźnie wskazuje kompilatorowi, czy jest świadomy istnienia istnienia klasy bazowej, używając modyfikatorów new lub override.

Proponuję interpretacji modyfikatory (lub jej brak) jako:

  • None - Autor jest nieświadomy istnienia metody klasy bazowej, a zatem nie może oczekiwać, aby wypełniać swoje kontrakt.

  • new - Autor zna metodę bazową i z jakiegokolwiek powodu napisał tę metodę, aby jej nie wypełniać.

  • override - Autor zna metodę bazową i jej kontrakt, a także napisał tę metodę, aby ją zrealizować.

Powodem domyślnie kompilator zakładając new ale z ostrzeżeniem, że w przypadkach, gdy metoda jest dodawane do klasy pochodnej, zanim kiedykolwiek istniała metoda baza klasy, nie może być ewentualnie spodziewać autorowi zostały świadomy umowy bazowej i nie może prawdopodobnie zawrzeć umowy, która jeszcze nie istniała, ale w przypadkach, w których metoda klasy pochodnej jest napisana po metodzie bazowej, autor powinien ogólnie wybrać inną nazwę, chyba że autor albo zamierza wypełnić umowę bazową, albo ma konkretny powód używania tej samej nazwy bez wypełniania umowy. Kompilator nie może stwierdzić, która metoda została napisana jako pierwsza, a zatem nie ma możliwości sprawdzenia, które zachowanie jest właściwe.

Powiązane problemy