Kann ich eine Eigenschaft in c # überschreiben? Wie?

76

Ich habe diese Basisklasse:

abstract class Base
{
  public int x
  {
    get { throw new NotImplementedException(); }
  }
}

Und der folgende Nachkomme:

class Derived : Base
{
  public int x
  {
    get { //Actual Implementaion }
  }
}

Wenn ich kompiliere, erhalte ich die Warnung, dass die Definition der abgeleiteten Klasse xdie Version von Base verbergen wird. Ist es möglich, Eigenschaften in c # -ähnlichen Methoden zu überschreiben?

atoMerz
quelle

Antworten:

96

Sie müssen ein virtualSchlüsselwort verwenden

abstract class Base
{
  // use virtual keyword
  public virtual int x
  {
    get { throw new NotImplementedException(); }
  }
}

oder definieren Sie eine abstrakte Eigenschaft:

abstract class Base
{
  // use abstract keyword
  public abstract int x { get; }
}

und verwenden Sie das overrideSchlüsselwort, wenn Sie im Kind sind:

abstract class Derived : Base
{
  // use override keyword
  public override int x { get { ... } }
}

Wenn Sie NICHT überschreiben möchten, können Sie das newSchlüsselwort für die Methode verwenden, um die Definition des übergeordneten Elements auszublenden.

abstract class Derived : Base
{
  // use new keyword
  public new int x { get { ... } }
}
Jeffrey Zhao
quelle
12

Machen Sie die Base-Eigenschaft abstrakt und überschreiben Sie das neue Schlüsselwort in der abgeleiteten Klasse oder verwenden Sie es.

abstract class Base
{
  public abstract int x { get; }
}

class Derived : Base
{
  public override int x
  {
    get { //Actual Implementaion }
  }
}

Oder

abstract class Base
{
  public int x { get; }
}

class Derived : Base
{
  public new int x
  {
    get { //Actual Implementaion }
  }
}
jrummell
quelle
4
Oder Sie könnten Virtual für die Basisklasse verwenden, wie Jeffrey Zhao erwähnte.
Jrummell
5

Ändern Sie die Eigenschaftssignatur wie unten gezeigt:

Basisklasse

public virtual int x 
{ get { /* throw here*/ } }

Abgeleitete Klasse

public override int x 
{ get { /*overriden logic*/ } }

Wenn Sie keine Implementierung in der Basisklasse benötigen, verwenden Sie einfach die abstrakte Eigenschaft.

Base:

public abstract int x { get; }

Abgeleitet:

public override int x { ... }

Ich würde vorschlagen, dass Sie die abstractEigenschaft verwenden, anstatt die NotImplemented-Ausnahme in getter auszulösen. Der abstactModifikator zwingt alle abgeleiteten Klassen, diese Eigenschaft zu implementieren, sodass Sie eine sichere Lösung zur Kompilierungszeit erhalten.

sll
quelle
3
abstract class Base 
{ 
  // use abstract keyword 
  public virtual int x 
  { 
    get { throw new NotImplementedException(); } 
  } 
} 
Matt Seymour
quelle
3
abstract class Base
{

  public virtual int x
  {
    get { throw new NotImplementedException(); }
  }
}

oder

abstract class Base
{
  // use abstract keyword
  public abstract int x
  {
    get;
  }
}

In beiden Fällen müssen Sie in die abgeleitete Klasse schreiben

public override int x
  {
    get { your code here... }
  }

Der Unterschied zwischen den beiden besteht darin, dass Sie mit abstract die abgeleitete Klasse zwingen, etwas zu implementieren, und mit virtaul können Sie ein Standardverhalten bereitstellen, das der Ableiter unverändert verwenden oder ändern kann.

Felice Pollano
quelle