Explizite Schnittstellen, um eine versehentliche Modifikation von Eigenschaften in C # zu verhindern

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

  •  19-09-2019
  •  | 
  •  

Frage

stieß ich auf ein Feature von C # Methode Auflösung, dass ich nicht vor bemerkt haben. Wenn nämlich implementiere ich explizit eine Schnittstelle, die Stützen ein Setter, und die implizite Schnittstelle bietet nur einen geschützten Satz, der Compiler vernünftig aufschiebt zum geschützten Satz, wenn ich es nennen. Also habe ich die meisten der Bequemlichkeit automatisch implementierte Eigenschaften bekommen, aber ich kann versehentliche Änderung von Feldern von Kunden verhindern wer sollte sie nicht sein ändern.

Als Beispiel

 virtual public DateTime CreatedOn { get; protected set; }
 virtual public DateTime? ModifiedOn { get; protected set; }
 #region IHaveUpdateDateFields Members

 DateTime IHaveUpdateDateFields.CreatedOn
 {
    get
    {
        return this.CreatedOn;
    }
    set
    {
        this.CreatedOn = value;
    }
}

DateTime? IHaveUpdateDateFields.ModifiedOn
{
    get
    {
        return this.ModifiedOn;
    }
    set
    {
        this.ModifiedOn = value;
    }
}

Dann ist mein Modell-Code verbindlich versehentlich gesetzt nicht den Zeitpunkt, aber meine ORM Ereignis-Listener kann für Unternehmen überprüfen, die IHaveUpdateDateFields implementieren und das Datum festgelegt, wenn meine Einheit persistierenden.

Meine Fragen sind:

  1. Bin ich auf definiertem Verhalten unter Berufung, oder bin ich garantiert, dass alle C # Compiler Methoden auf diese Weise lösen wird? Ich will nicht entdecken, dass der C # Standard sagt diese Art von Verfahren Auflösung nicht definiert ist und dann aus Versehen einen erschreckenden Stack-Überlauf, wenn ich für Mono, zum Beispiel bauen.
  2. Gibt es eine schönere (idealerweise knappere) Weg, dies zu tun? Ich könnte einen Modelbinder-sichere Schnittstelle habe, dass ich meinen Controller passieren, aber das scheint nicht, wie es mir Code speichern würde, und ich glaube nicht, dass so transparent, einen Ansatz zur Minimierung versehentliche Änderung von Eigenschaften bieten würde.
War es hilfreich?

Lösung

Das ist sehr gut definiert ist; die expliziten Schnittstellenimplementierungen haben Vorrang, wenn die Schnittstelle, und die regelmäßige Eigenschaft wirksam sonst (einschließlich aus dem Körper der get / set).

Was macht es aufgeräumter ... das Beste, was ich anbieten kann, ist es neu zu formatieren, um es weniger ausführlich ...

DateTime IHaveUpdateDateFields.CreatedOn
{
    get { return CreatedOn; }
    set { CreatedOn = value; }
}

(beachten Sie auch, dass der this ist implizit und redundant)

Als beiseite - die Sicherheit ist nur eine Bequemlichkeit, keine Garantie ... externe Anrufer immer noch Ihre Schnittstelle verwenden können, und in der Regel kann (ab) Verwendung Reflexion über bloße Dinge wie protected zu springen - oder sogar eingestellt nur die Felder direkt an.

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