Entwickler-Ecke

C# - Die Sprache - Der Sinn des 'new' Keywords


Kasko - Fr 31.05.19 01:36
Titel: Der Sinn des 'new' Keywords
Servus,

Die Nutzung des 'new' Keywords zur Erstellung/Initialisierung von Objekten ist ja glasklar, sinnvoll und nicht anzuzweifeln. Aber ich verstehe nicht warum die Funktion in C# eingebaut wurde, dass man mit dem 'new' Keyword einfach Properties, etc. einer Basisklasse überschreiben kann. Dadurch wird doch das Prinzip der objektorientierten Kapselung zerstört. Ein Beispiel:


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
public class Mensch {
  protected string _name;

  /// <summary>
  /// Ruft den Namen des Menschen ab. Man kann ihn natürlich nicht einfach so ändern. Geht im echten Leben ja auch nicht.
  /// </summary>
  public string Name { get => _name; }

  /// <summary>
  /// 'Erstellt' einen Menschen und legt bei 'der Geburt' den Namen fest.
  /// </summary>
  /// <param name="name">Der Name des Menschen.</param>
  public Mensch(string name) {
    _name = name;
  }
}


So wäre es logisch. Aber warum kann ich jetzt die Property 'Name' in einer erbenden Klasse neu definieren. Das zerstört ja das ganze Verhalten das vorher, vielleicht sogar von einem anderen Programmierer, festgelegt wurde. Dann würde das Kind ja seinem Parent widersprechen!!!


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
public class UmbenennbarerMensch : Mensch {
  /// <summary>
  /// Ruft den Namen des Menschen ab oder legt diesen fest. Aus irgendeinem Grund soll man jetzt den Namen ändern können, obwohl es eigentlich anders vereinbart wurde.
  /// <see cref="Mensch"/>
  /// Sinn dahinter ist anzuzweifeln.
  /// </summary>
  public new string Name { get => _name; set => _name = value; }

  /// <summary>
  /// 'Erstellt' einen Menschen und legt bei 'der Geburt' den Namen fest.
  /// </summary>
  /// <param name="name">Der Name des Menschen.</param>
  public UmbenennbarerMensch(string name) : base(name){ }
}


Kann mir das bitte jemand erklären, warum man sowas machen darf?


Th69 - Fr 31.05.19 09:21

Damit wird den C#-Programmierern alle Möglichkeiten geboten.
Für virtual-Methoden gibt es override und für nicht-virtuelle (welche ja Standard sind, im Gegensatz zu z.B. Java) gibt es eben new. In Polymorphism, Method Hiding and Overriding in C# [https://www.akadia.com/services/dotnet_polymorphism.html] wird das auch detailliert dargestellt.

Und ohne den new-Modifizierer [https://docs.microsoft.com/de-de/dotnet/csharp/language-reference/keywords/new-modifier] kommt ja eine entsprechende Warnung "The keyword new is required on 'MyDerivedC.X' because it hides inherited member 'MyBaseC.X'.

Und manchmal benötigt man eben Ausnahmen, z.B. wenn man beim Heiraten den Nachnamen des Partners annimmt (um bei deinem Beispiel zu bleiben).


OlafSt - Fr 31.05.19 10:08

Bieten nicht alle objektorientierten Sprachen so eine Möglichkeit ? In Delphi gibt es dafür z.B. das Keyword reintroduce.


Palladin007 - Fr 31.05.19 10:35

Zitat:
Dadurch wird doch das Prinzip der objektorientierten Kapselung zerstört

Finde ich, trifft's ganz gut :D

Ich behaupte auch, es gibt fast keinen sinnvollen Anwendungsfall, aber es ist trotzdem dabei, damit man die Möglichkeit hat, falls man sie doch Mal braucht.

Ich persönlich nutze das eigentlich nur in z.B. so einem Fall:


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
public class Entry
{
    public object Value { get; }

    public Entry(object value)
    {
        Value = value;
    }
}

public class Entry<TValue> : Entry
{
    public new TValue Value
    {
        get => (TValue)base.Value;
    }

    public Entry(TValue value)
       : base(value)
    {
    }
}


Damit verändere ich das Grundverhalten nicht, ich den selben Wert an, nur mit einem Cast.
Ob das jetzt so gut ist, kann man drüber streiten und im Zweifelsfall ist mir auch das Interface mit explizit implementierter Value-Property lieber.


Th69 - Fr 31.05.19 10:59

@Palladin007: Du meinst sicherlich

C#-Quelltext
1:
public class Entry<TValue> : Entry                    
?


Palladin007 - Fr 31.05.19 19:15

Ja genau, das meine ich.
Danke für die Korrektur, hab's oben angepasst.