Warum ist es nicht möglich, eine Getter geschützte Eigenschaft außer Kraft zu setzen und einen Setter hinzufügen? [geschlossen]

StackOverflow https://stackoverflow.com/questions/82437

Frage

Warum wird das folgende C # -Code nicht zulässig:

public abstract class BaseClass
{
    public abstract int Bar { get;}
}

public class ConcreteClass : BaseClass
{
    public override int Bar
    {
        get { return 0; }
        set {}
    }
}
  

CS0546 'ConcreteClass.Bar.set': kann nicht außer Kraft setzen, weil 'BaseClass.Bar' keinen overridable set-Accessor hat

War es hilfreich?

Lösung

Da die Schreiber hat ausdrücklich erklärt Basisklasse, dass Bar hat eine schreibgeschützte Eigenschaft sein. Es macht keinen Sinn für Ableitungen, diesen Vertrag zu brechen und es read-write machen.

Ich bin mit Microsoft auf diesem.
Lassen Sie uns sagen, dass ich ein neuer Programmierer bin, der gegen die Basisklasse Ableitung Code gesagt wurde. Ich schreibe etwas, das davon ausgeht, dass Bar kann nicht geschrieben werden (da die Basisklasse erklärt ausdrücklich, dass es sich um eine einzige Eigenschaft ist zu erhalten). Jetzt mit Ableitung kann mein Code brechen. z.

public class BarProvider
{ BaseClass _source;
  Bar _currentBar;

  public void setSource(BaseClass b)
  {
    _source = b;
    _currentBar = b.Bar;
  }

  public Bar getBar()
  { return _currentBar;  }
}

Da Bar kann nicht im Rahmen der Baseclass-Schnittstelle eingestellt werden, wird davon ausgegangen, dass BarProvider Caching eine sichere Sache zu tun - Da Bar kann nicht geändert werden. Aber wenn Satz ist möglich, in einer Ableitung, könnte diese Klasse abgestanden Werte werden dienen, wenn jemand das _Source Objekts Bar Eigenschaft extern geändert. Der Punkt ist ' offen, vermeiden tun hinterhältige Dinge und überraschende Menschen

Aktualisieren : Ilya Ryzhenkov fragt: 'Warum Schnittstellen nicht nach den gleichen Regeln spielen dann?' Hmm .. das wird trüber als ich darüber nachdenke.
Eine Schnittstelle ist ein Vertrag, der sagt: ‚erwarten eine Implementierung eine Eigenschaft mit dem Namen lesen Bar zu haben.‘ Persönlich Ich bin viel weniger wahrscheinlich, dass die Annahme von schreibgeschützt zu machen, wenn ich eine Schnittstelle sehe. Wenn ich eine get-Unterkunft, die nur auf einer Schnittstelle zu sehen, las ich es als ‚jede Implementierung würde dieses Attribut Bar aussetzen‘ ... auf einer Basis-Klasse ein Klicken zu hören als ‚Bar ist eine schreibgeschützte Eigenschaft‘. Natürlich technisch brechen Sie den Vertrag nicht .. du bist mehr zu tun. Also du hast Recht in gewisser Hinsicht .. ich sagen, ‚es so schwer wie möglich machen für Missverständnisse auftauchen‘ schließen würde.

Andere Tipps

Ich denke, der Hauptgrund dafür ist einfach, dass die Syntax zu explizit für diese andere Art und Weise zu arbeiten. Dieser Code:

public override int MyProperty { get { ... } set { ... } }

ist ganz deutlich, dass sowohl die get und die set Überschreibungen sind. Es gibt keine set in der Basisklasse, so dass der Compiler beschwert. Genau wie Sie können nicht eine Methode überschreiben, die nicht in der Basisklasse definiert sind, können Sie nicht einen Setter entweder außer Kraft setzen.

Sie könnte sagen, dass der Compiler Ihre Absicht erraten sollte und nur die Überschreibung der Methode anwenden, (dh der Getter in diesem Fall) außer Kraft gesetzt werden kann, aber das geht gegen eine der C # Design-Prinzipien -, dass der Compiler muss nicht erraten, Ihre Absichten, weil es falsch erraten kann, ohne Sie zu kennen.

Ich denke, die folgende Syntax gut tun könnte, aber wie Eric Lippert sagen hält, Implementierung auch eine untergeordnete Funktion wie diese immer noch eine große Menge an Aufwand ist ...

public int MyProperty
{
    override get { ... }
    set { ... }
}

oder, für autoimplemented Eigenschaften,

public int MyProperty { override get; set; }

Ich stolperte über das gleiche Problem heute und ich denke, dass ein für den Wunsch, das einen sehr triftigen Grund hat.

Zuerst würde Ich mag argumentieren, dass eine get-Unterkunft, die nur mit unbedingt übersetzt nicht in schreibgeschützt. Ich interpretiere es als „Von dieser Schnittstelle / abtract Sie diesen Wert bekommen kann“, bedeutet dies jedoch nicht, dass einige Implementierung dieser Schnittstelle / abstrakte Klasse pflegen müssen die Benutzer / Programm diesen Wert explizit setzen. Abstrakte Klassen dienen dazu, einen Teil der benötigten Funktionalität zu implementieren. Ich sehe absolut keinen Grund, warum eine vererbte Klasse keinen Setter ohne Verletzung keine Verträge hinzufügen könnte.

Das folgende ist ein vereinfachtes Beispiel von dem, was ich heute gebraucht. Ich landete mit einem Setter in meiner Schnittstelle fügen Sie einfach, dies zu umgehen. Der Grund für die Setter-Zugabe und nicht hinzufügen, sagen wir, ein SetProp Verfahren ist, dass eine bestimmte Implementierung der Schnittstelle Datacontract / Datamember für die Serialisierung von Prop verwendet, die unnötig kompliziert gemacht worden wäre, wenn ich für den Zweck eine andere Eigenschaft nur hinzufügen, hatte die Serialisierung.

interface ITest
{
    // Other stuff
    string Prop { get; }
}

// Implements other stuff
abstract class ATest : ITest
{
    abstract public string Prop { get; }
}

// This implementation of ITest needs the user to set the value of Prop
class BTest : ATest
{
    string foo = "BTest";
    public override string Prop
    {
        get { return foo; }
        set { foo = value; } // Not allowed. 'BTest.Prop.set': cannot override because 'ATest.Prop' does not have an overridable set accessor
    }
}

// This implementation of ITest generates the value for Prop itself
class CTest : ATest
{
    string foo = "CTest";
    public override string Prop
    {
        get { return foo; }
        // set; // Not needed
    }
}

Ich weiß, das ist nur ein „my 2 cents“ post, aber ich fühle mich mit dem Original-Poster und versuchen, zu rationalisieren, dass dies eine gute Sache scheint mir seltsam ist, besonders wenn man bedenkt, dass die gleichen Beschränkungen gelten nicht, wenn vererben direkt von einer Schnittstelle.

Auch die Erwähnung über die Verwendung von neuen anstelle von Überschreibung gilt hier nicht, es funktioniert einfach nicht und selbst wenn es nicht Sie tut würde das Ergebnis wollte, nämlich ein virtuelles Getter, wie durch die Schnittstelle beschrieben.

Es ist möglich

tl; dr - Sie können eine get-only-Methode mit einem Setter überschreiben, wenn Sie wollen. Es ist im Grunde nur:

  1. Erstellen Sie eine new Eigenschaft, die sowohl eine get und eine set den gleichen Namen verwenden.

  2. Wenn Sie tun nichts anderes, dann der alte get Methode wird noch aufgerufen werden, wenn die abgeleitete Klasse durch seinen Basistyp bezeichnet wird. Um dies zu beheben, fügen Sie eine abstract Zwischenschicht, die override auf der alten get Methode verwendet sie zu zwingen, die neue get Methode des Ergebnis zurück.

Dies ermöglicht es uns, Eigenschaften mit get / set außer Kraft zu setzen, auch wenn sie fehlte eine in ihrer Basis-Definition.

Als Bonus können Sie auch den Rückgabetyp ändern, wenn Sie möchten.

  • Wenn die Basisdefinition wurde nur get-, dann können Sie einen verwenden Rückgabetyp mehr abgeleiteten.

  • Wenn die Basisdefinition wurde set-only, dann können Sie uns einen weniger abgeleiteten Rückgabetyp.

  • Wenn die Basisdefinition wurde bereits get / set, dann:

    • Sie können verwenden mehr abgeleiteten Rückgabetyp , wenn Sie machen es set-only;

    • Sie können mit weniger abgeleiteten Rückgabetyp , wenn Sie machen es get geschützt.

In allen Fällen können Sie den gleichen Rückgabetyp behalten, wenn Sie wollen. Die folgenden Beispiele verwenden den gleichen Rückgabetyp für Einfachheit.

Situation: Bereits bestehende get geschützte Eigenschaft

Sie haben einige Klassenstruktur, die Sie nicht ändern können. Vielleicht ist es nur eine Klasse, oder es ist ein vorbestehende Vererbungsbaum. Was auch immer der Fall ist, möchten Sie eine set Methode auf eine Eigenschaft hinzufügen, aber nicht kann.

public abstract class A                     // Pre-existing class; can't modify
{
    public abstract int X { get; }          // You want a setter, but can't add it.
}
public class B : A                          // Pre-existing class; can't modify
{
    public override int X { get { return 0; } }
}

Problem: Kann nicht override die get-nur mit get / set

Sie mögen mit einer override / get Eigenschaft set, aber es wird nicht kompiliert werden.

public class C : B
{
    private int _x;
    public override int X
    {
        get { return _x; }
        set { _x = value; }   //  Won't compile
    }
}

Lösung: Verwenden Sie eine abstract Zwischenschicht

Sie können zwar nicht direkt mit einem override / get Eigenschaft set können Sie können :

  1. Erstellen Sie eine new get / set Eigenschaft mit dem gleichen Namen.

  2. override die alte get Methode mit einem Accessor auf die neue get Methode Konsistenz zu gewährleisten.

Also, zuerst schreiben Sie die abstract Zwischenschicht:

public abstract class C : B
{
    //  Seal off the old getter.  From now on, its only job
    //  is to alias the new getter in the base classes.
    public sealed override int X { get { return this.XGetter; }  }
    protected abstract int XGetter { get; }
}

Dann schreiben Sie die Klasse, die früher nicht kompilieren würde. Es wird dieses Mal kompilieren, weil Sie nicht wirklich die override geschützte Eigenschaft get'ing; stattdessen Sie ersetzen das new Schlüsselwort.

public class D : C
{
    private int _x;
    public new virtual int X { get { return this._x; } set { this._x = value; } }

    //  Ensure base classes (A,B,C) use the new get method.
    protected sealed override int XGetter { get { return this.X; } }
}

Ergebnis: Alles funktioniert

Natürlich funktioniert dies as sollte für D.

var test = new D();
Print(test.X);      // Prints "0", the default value of an int.

test.X = 7;
Print(test.X);      // Prints "7", as intended.

Alles noch Arbeiten as vorgesehen, wenn D als eine ihrer Basisklassen sehen, zum Beispiel A oder B. Aber der Grund, warum es funktioniert vielleicht etwas weniger offensichtlich sein.

var test = new D() as B;
//test.X = 7;       // This won't compile, because test looks like a B,
                    // and B still doesn't provide a visible setter.

die Basisklasse Definition von get jedoch nach wie vor wird letztlich von der abgeleiteten Klasse Definition von get außer Kraft gesetzt, so ist es immer noch völlig im Einklang.

var test = new D();
Print(test.X);      // Prints "0", the default value of an int.

var baseTest = test as A;
Print(test.X);      // Prints "7", as intended.

Diskussion

Mit dieser Methode können Sie set Methoden get geschützte Eigenschaften hinzuzufügen. Sie können auch wie Dinge zu tun verwenden:

  1. Ändern Sie jede Eigenschaft in eine get-only, set-only oder get-and-set Eigenschaft, unabhängig davon, was eswar in einer Basisklasse.

  2. Ändern Sie den Rückgabetyp einer Methode in abgeleiteten Klassen.

Die wichtigsten Nachteile sind, dass es mehr Codierung ist und ein extra abstract class im Vererbungsbaum zu tun. Dies kann ein wenig nervig mit Konstrukteuren, die Parameter übernehmen, weil die haben in der Zwischenschicht kopiert / eingefügt werden.

Ich bin damit einverstanden, dass kein Getter in einem abgeleiteten Typ in der Lage, außer Kraft zu setzen ist ein Anti-Muster. Read-Only gibt mangelnde Umsetzung, kein Vertrag einen reinen Funktions (implizierten oben Stimme Antwort).

Ich vermute, dass Microsoft diese Einschränkung hatte, entweder weil das gleiche Missverständnis gefördert wurde, oder vielleicht gerade wegen der Grammatik vereinfacht werden; aber jetzt kann man erkennen, Umfang angewendet werden individuell und festlegen, können wir vielleicht überschreiben hoffen sein.

Die falsche Vorstellung von der Spitze der Abstimmung Antwort angegeben, dass eine schreibgeschützte Eigenschaft irgendwie mehr sein sollte „rein“ ist als ein Lese / Schreib-Eigenschaft ist lächerlich. Einfach auf viele gemeinsame Lese nur Objekte im Rahmen; der Wert ist keine Konstante / rein funktional; zum Beispiel wird DateTime.Now nur gelesen, aber alles andere als ein rein funktionalen Wert. Ein Versuch, ‚Cache‘ unter der Annahme eines Wert von einer Nur-Lese-Eigenschaft wird es den gleichen Wert beim nächsten Mal ist riskant zurück.

Auf jeden Fall habe ich eine der folgenden Strategien verwendet diese Einschränkung zu überwinden; beide sind weniger als perfekt, aber ermöglicht es Ihnen, über diese Sprache Mangel hinken:

   class BaseType
   {
      public virtual T LastRequest { get {...} }
   }

   class DerivedTypeStrategy1
   {
      /// get or set the value returned by the LastRequest property.
      public bool T LastRequestValue { get; set; }

      public override T LastRequest { get { return LastRequestValue; } }
   }

   class DerivedTypeStrategy2
   {
      /// set the value returned by the LastRequest property.
      public bool SetLastRequest( T value ) { this._x = value; }

      public override T LastRequest { get { return _x; } }

      private bool _x;
   }

Sie vielleicht, um das Problem gehen könnten eine neue Eigenschaft durch die Schaffung von:

public new int Bar 
{            
    get { return 0; }
    set {}        
}

int IBase.Bar { 
  get { return Bar; }
}

kann ich alle Punkte verstehen, aber effektiv, C # 3.0 automatische Eigenschaften erhalten nutzlos in diesem Fall.

Sie können nicht so etwas tun:

public class ConcreteClass : BaseClass
{
    public override int Bar
    {
        get;
        private set;
    }
}

IMO sollte C # nicht solche Szenarien beschränken. Es ist die Verantwortung der Entwickler entsprechend zu verwenden.

Das Problem ist, dass aus irgendeinem Grunde Microsoft entschieden, dass es drei verschiedene Arten von Eigenschaften sein sollte: schreibgeschützt, schreibgeschützt und Lese-Schreib, von denen nur einer mit einer bestimmten Signatur in einem bestimmten Kontext existieren kann; Eigenschaften können nur durch gleich deklarierten Eigenschaften außer Kraft gesetzt werden. Zu tun, was Sie wollen, dass es notwendig wäre, zwei Objekte mit dem gleichen Namen zu erstellen und Unterschrift -. Einer davon war schreibgeschützt, und von denen ein Lese-Schreib-

Ich persönlich wünsche, dass das gesamte Konzept der „Eigenschaften“ abgeschafft werden könnte, außer dieser Eigenschaft-ish Syntax könnte als syntaktischer Zucker verwendet werden, um zu nennen „get“ und „set“ Methoden. Dies würde nicht nur die ‚add gesetzt‘ Option, sondern auch für ‚get‘ ermöglicht einen anderen Typen zurückzukehren, von ‚Set‘. Während eine solche Fähigkeit nicht sehr oft verwendet werden würde, könnte es manchmal sinnvoll sein, ein ‚get‘ zu haben Methode ein Wrapper-Objekt zurück, während die ‚Set‘ entweder einen Wrapper oder tatsächlichen Daten übernehmen könnte.

Hier ist eine Behelfslösung, um dies mit Reflexion zu erreichen:

var UpdatedGiftItem = // object value to update;

foreach (var proInfo in UpdatedGiftItem.GetType().GetProperties())
{
    var updatedValue = proInfo.GetValue(UpdatedGiftItem, null);
    var targetpropInfo = this.GiftItem.GetType().GetProperty(proInfo.Name);
    targetpropInfo.SetValue(this.GiftItem, updatedValue,null);
}

So können wir Objektwert auf eine Eigenschaft festlegen, die nur lesbar ist. Könnte allerdings nicht in allen Szenarien arbeiten!

Sie sollen Ihre Frage Titel entweder Detail ändern, dass Ihre Frage zu überschreiben eine abstrakte Eigenschaft nur in Bezug ist, oder dass Ihre Frage in Bezug zu zwingender Regel einer get-only Klasse Eigenschaft.


Wenn das ehemalige (Überschreiben eine abstrakte Eigenschaft)

Dieser Code ist nutzlos. Eine Basisklasse allein sollte man nicht sagen, dass Sie eine Get-Only-Eigenschaft (Vielleicht ein Interface) sind gezwungen, außer Kraft zu setzen. Eine Basisklasse bietet gemeinsame Funktionalität, die spezifische Eingabe von einem implementierenden Klasse erfordern. Daher kann die gemeinsame Funktionalität Anrufe abstrakte Eigenschaften oder Methoden. Im gegebenen Fall sollten die gemeinsame Funktionalität Methoden fragen, für Sie eine abstrakte Methode wie außer Kraft zu setzen:

public int GetBar(){}

Aber wenn Sie keine Kontrolle über das haben, und die Funktionalität der Basisklasse liest aus seinem eigenen öffentlichen Eigentum (komisch), dann ist dies nur tun:

public abstract class BaseClass
{
    public abstract int Bar { get; }
}

public class ConcreteClass : BaseClass
{
    private int _bar;
    public override int Bar
    {
        get { return _bar; }
    }
    public void SetBar(int value)
    {
        _bar = value;
    }
}

Ich mag den (komisch) Kommentar hinweisen: Ich würde sagen, eine Best-Practice für eine Klasse ist nicht seine eigenen öffentlichen Eigenschaften zu verwenden, aber seine privaten / geschützten Felder zu verwenden, wenn sie existieren. Das ist also ein besseres Muster:

public abstract class BaseClass {
    protected int _bar;
    public int Bar { get { return _bar; } }
    protected void DoBaseStuff()
    {
        SetBar();
        //Do something with _bar;
    }
    protected abstract void SetBar();
}

public class ConcreteClass : BaseClass {
    protected override void SetBar() { _bar = 5; }
}

Wenn letzteres (Überschreiben einer Klasse get-only-Eigenschaft)

Jede nicht-abstrakte Eigenschaft hat einen Setter. Sonst ist es nutzlos, und Sie sollten es nicht benutzen kümmern. Microsoft hat Ihnen nicht zu erlauben, zu tun, was Sie wollen. Grund dafür ist:. Die Setter existiert in irgendeiner Form oder eine andere, und Sie können erreichen, was Sie wollen Veerryy leicht

Die Basisklasse oder jede Klasse, wo Sie eine Eigenschaft mit {get;} lesen kann, hat SOME Art ausgesetzt Setter für diese Eigenschaft. Die Metadaten werden wie folgt aussehen:

public abstract class BaseClass
{
    public int Bar { get; }
}

Aber die Umsetzung wird zwei Enden des Spektrums der Komplexität haben:

Least Complex:

public abstract class BaseClass
{
    private int _bar;
    public int Bar { 
        get{
            return _bar;
        }}
    public void SetBar(int value) { _bar = value; }
}

Die meisten Komplexe:

public abstract class BaseClass
{
    private int _foo;
    private int _baz;
    private int _wtf;
    private int _kthx;
    private int _lawl;

    public int Bar
    {
        get { return _foo * _baz + _kthx; }
    }
    public bool TryDoSomethingBaz(MyEnum whatever, int input)
    {
        switch (whatever)
        {
            case MyEnum.lol:
                _baz = _lawl + input;
                return true;
            case MyEnum.wtf:
                _baz = _wtf * input;
                break;
        }
        return false;
    }
    public void TryBlowThingsUp(DateTime when)
    {
        //Some Crazy Madeup Code
        _kthx = DaysSinceEaster(when);
    }
    public int DaysSinceEaster(DateTime when)
    {
        return 2; //<-- calculations
    }
}
public enum MyEnum
{
    lol,
    wtf,
}

Mein Punkt ist, so oder so, Sie haben die Setter ausgesetzt. In Ihrem Fall, können Sie int Bar außer Kraft zu setzen, weil Sie damit umgehen nicht die Basisklasse wollen, haben keinen Zugang zu überprüfen, wie es es Handhabung oder wurden einige Code echte quick'n'dirty gegen Ihre zu hax beauftragt wird.

In den beiden Letzten und ehemalige (Schlussfolgerung)

Long-Story Short: Es ist nicht notwendig für Microsoft etwas zu ändern. Sie können wählen, wie Sie Ihre Implementierungsklasse eingerichtet ist und, sans der Konstruktor, alle oder keine der Basisklasse verwendet werden.

Lösung für nur eine kleine Teilmenge von Anwendungsfällen, aber trotzdem:. In C # 6.0 "Read-only" Setter automatisch außer Kraft gesetzt Getter-only Eigenschaften hinzugefügt wird

public abstract class BaseClass
{
    public abstract int Bar { get; }
}

public class ConcreteClass : BaseClass
{
    public override int Bar { get; }

    public ConcreteClass(int bar)
    {
        Bar = bar;
    }
}

Weil am IL-Ebene, eine Lese / Schreib-Eigenschaft führt zu zwei (Getter und Setter) -Methoden.

Wenn überschreiben, müssen Sie die zugrunde liegende Schnittstelle halten zu unterstützen. Wenn Sie einen Setter hinzufügen könnten, würden Sie effektiv ein neues Verfahren das Hinzufügen, die an die Außenwelt unsichtbar bleiben würde, so weit wie Ihre Klassen-Schnittstelle anging.

Es stimmt, würde eine neue Methode Zugabe nicht per se brechen Kompatibilität, aber da es verborgen bleiben würde, Entscheidung zu verbieten dies durchaus Sinn macht.

Denn das würde das Konzept der Kapselung und Implementierung Versteck brechen. Betrachten wir den Fall, wenn Sie eine Klasse erstellen, versenden sie, und dann wird der Verbraucher der Klasse macht sich der Lage, eine Eigenschaft zu setzen, für die Sie ursprünglich nur einen Getter zur Verfügung stellen. Es wäre effektiv alle Invarianten Ihrer Klasse stören, die Sie in Ihrer Implementierung hängen von können.

Da eine Klasse, die eine schreibgeschützte Eigenschaft hat (kein Setter) wahrscheinlich einen guten Grund dafür hat. Es könnte nicht zugrunde liegende Datenspeicher sein, zum Beispiel. So dass Sie eine Setter erstellen bricht den Vertrag durch die Klasse angegeben. Es ist nur schlecht OOP.

A schreibgeschützte Eigenschaft in der Basisklasse zeigt an, dass diese Eigenschaft einen Wert repräsentiert, die immer aus der Klasse bestimmt werden kann (zum Beispiel eines ENUM-Wert des (db-) Kontext eines Objekts entspricht). So ist der responsibillity den Wert zu bestimmen, bleibt innerhalb der Klasse.

ein Setter Hinzufügen verursachen würde eine peinliche Frage hier: Ein Validierungsfehler auftreten soll, wenn Sie den Wert auf etwas anderes als den einzigen möglichen Wert eingestellt es bereits hat.

Die Regeln haben oft Ausnahmen. Es ist sehr gut möglich, dass zum Beispiel in einer abgeleiteten Klasse der Kontext die möglichen ENUM-Werte von bis zu 3 von 10 verengt, doch der Benutzer dieses Objekts muss noch entscheiden, welches korrekt ist. Die abgeleitete Klasse braucht die responsibillity des Bestimmens des Wertes für den Benutzer dieses Objekts zu delegieren. Wichtig zu erkennen ist, dass der Benutzer dieses Objekts sollte diese Ausnahme auch darüber im Klaren sein und übernimmt die responsibillity den richtigen Wert zu setzen.

Meine Lösung in dieser Art von Situationen wäre es, die Eigenschaft schreibgeschützt zu verlassen und eine neue Lese-Schreib-Eigenschaft der abgeleiteten Klasse hinzufügen, um die Ausnahme zu unterstützen. Die Überschreibung der ursprünglichen Eigenschaft wird einfach den Wert der neuen Eigenschaft zurück. Die neue Eigenschaft kann einen richtigen Namen hat den Kontext dieser Ausnahme richtig angezeigt wird.

Dies unterstützt auch die gültige Bemerkung: „macht es so schwer wie möglich für Missverständnisse auftauchen“ von Gishu

.

Dies ist nicht unmöglich. Sie müssen einfach nur die „neue“ Keyword in Ihrer Eigenschaft verwenden. Zum Beispiel:

namespace {
    public class Base {
        private int _baseProperty = 0;

        public virtual int BaseProperty {
            get {
                return _baseProperty;
            }
        }

    }

    public class Test : Base {
        private int _testBaseProperty = 5;

        public new int BaseProperty {
            get {
                return _testBaseProperty;
            }
            set {
                _testBaseProperty = value;
            }
        }
    }
}

Es scheint, als ob dieser Ansatz beiden Seiten dieser Diskussion genügt. Mit „neuen“ bricht den Vertrag zwischen der Basisklassenimplementierung und der Unterklasse Implementierung. Dies ist notwendig, wenn eine Klasse mehrere Verträge haben kann (entweder über die Schnittstelle oder Basisklasse).

Hope, das hilft

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top