Das Backing-Feld in einer Auto-Eigenschaft einbeziehen

8

Gibt es eine Möglichkeit, auf das Hintergrundfeld für eine Eigenschaft zuzugreifen, um Validierung, Änderungsverfolgung usw. durchzuführen?

Ist etwas wie das Folgende möglich? Wenn nicht, gibt es Pläne, es in .NET 4 / C # 4 zu haben?

%Vor%

Das Hauptproblem, das ich habe, ist, dass die Verwendung automatischer Eigenschaften nicht die gleiche Flexibilität bei der Validierung usw. erlaubt, wie eine Eigenschaft mit einem expliziten Hintergrundfeld. Ein explizites Unterstützungsfeld hat jedoch in einigen Situationen den Nachteil, dass es der Klasse, in der es enthalten ist, ermöglicht, auf das Unterstützungsfeld zuzugreifen, wenn es auf die Validierung, Änderungsverfolgung usw. der Eigenschaft zugreift und diese erneut verwendet, wie jede andere Klasse, auf die zugegriffen werden kann die Eigenschaft extern.

Im obigen Beispiel würde der Zugriff auf das Hintergrundfeld auf die Eigenschaft beschränkt, um eine Umgehung der Eigenschaftenvalidierung, Änderungsverfolgung usw. zu verhindern.

Bearbeiten: Ich habe & lt; Hintergrundfeld & gt; zu & lt; Schlüsselwort & gt ;. Ich würde ein neues Schlüsselwort ähnlich dem Wert vorschlagen. Feld würde gut funktionieren, obwohl ich sicher bin, dass es in einer Menge vorhandenen Codes verwendet wird.

    
Jonathan Parker 15.03.2009, 22:38
quelle

6 Antworten

3

Nachdem ich Ihre Kommentare in Mehrdads Antwort gelesen habe, glaube ich, dass ich Ihr Problem ein wenig besser verstehe.

Offenbar machen Sie sich Sorgen über die Fähigkeit des Entwicklers, in der Klasse, die er schreibt, auf den privaten Status zuzugreifen, indem er Ihre Validierungslogik usw. umgeht. Dies legt nahe, dass der Status überhaupt nicht in der Klasse enthalten sein sollte.

Ich würde die folgende Strategie vorschlagen. Schreiben Sie eine generische Klasse, die einen ValidatedValue darstellt. Diese Klasse enthält nur den Backing-Wert und erlaubt nur Zugriff / Mutation über get- und set-Methoden. Ein Delegat wird an ValidatedValue übergeben, um die Validierungslogik darzustellen:

%Vor%

Sie können natürlich nach Bedarf weitere Delegierte hinzufügen (z. B. zur Unterstützung der Benachrichtigung vor und nach der Änderung).

Ihre Klasse würde jetzt ValidatedValue anstelle eines Sicherungsspeichers für Ihre Eigenschaft verwenden.

Das folgende Beispiel zeigt eine Klasse MyClass mit einer Ganzzahl, die als kleiner als 100 validiert wird. Beachten Sie, dass die Logik zum Auslösen einer Ausnahme in MyClass und nicht in ValidatedValue liegt. Auf diese Weise können Sie komplexe Validierungsregeln ausführen, die von anderen in MyClass enthaltenen Status abhängen. Lambda-Notation wurde verwendet, um den Validierungsdelegaten zu konstruieren - Sie könnten stattdessen an eine Mitgliedsfunktion gebunden haben.

%Vor%

Ich hoffe, das hilft - etwas vom ursprünglichen Thema entfernt, aber ich denke, es ist mehr mit Ihren tatsächlichen Anliegen verbunden. Was wir getan haben, ist die Validierungslogik weg von der Eigenschaft und legte sie auf die Daten, die genau dort sind, wo Sie es haben wollten.

    
Daniel Paull 16.03.2009, 00:49
quelle
13

Nein, ist es nicht. Wenn Sie auf das Hintergrundfeld zugreifen möchten, verwenden Sie keine automatischen Eigenschaften und rollen Sie Ihre eigenen.

Ich stimme zu, dass es großartig wäre, ein Feld zu haben, das nur für die Eigenschaft und nicht für den Rest der Klasse zugänglich ist. Ich würde das immer benutzen.

    
Ray 15.03.2009 22:42
quelle
6

Wie in der MSDN angegeben ist:

  

"In C # 3.0 und höher, automatisch implementiert   Eigenschaften machen Property-Deklaration   prägnanter, wenn keine zusätzliche Logik   ist in den Eigenschaftenaccessoren erforderlich.   Sie ermöglichen auch das Erstellen von Clientcode   Objekte Wenn Sie eine Eigenschaft als deklarieren   Im folgenden Beispiel wird der   Compiler erstellt einen privaten, anonymen   Hintergrundfeld kann nur zugegriffen werden   durch das Eigentum wird und eingestellt   Accessoren. "

Da Sie in Ihren Accessoren über zusätzliche Logik verfügen, ist die Verwendung von automatisch implementierten Eigenschaften in Ihrem Szenario nicht geeignet.

Während das Backing-Feld existiert, wird es mit einem Namen versehen, damit Sie es nicht so leicht referenzieren können - die Idee ist, dass Sie niemals direkt auf das Feld verweisen . Aus Interesse, können Sie Reflektor verwenden, um Ihren Code zu zerlegen und den Feldnamen zu entdecken, aber ich würde empfehlen, dass Sie das Feld nicht direkt verwenden, da dieser Name tatsächlich flüchtig sein kann, also könnte Ihr Code jederzeit brechen.

    
Daniel Paull 15.03.2009 23:06
quelle
2

Nein, aber Sie können in einer Unterklasse:

%Vor%     
strager 16.03.2009 01:35
quelle
1

Wenn Sie das tun, warum verwenden Sie automatische Eigenschaften?!

Eine einfache Eigenschaft hat es in 1.0 geschafft. Ich glaube nicht, dass es sinnvoll ist, die Sprache für jeden Spezialfall etwas komplexer zu gestalten. Entweder benötigen Sie die Eigenschaft, um ein einfaches Store / Retrieve-Modell zu erstellen, oder Sie benötigen mehr. Im letzteren Fall reicht eine normale Eigenschaft aus.

    
Mehrdad Afshari 15.03.2009 22:40
quelle
1

Sie können das nicht tun, fürchte ich. Das ist einer der Gründe, warum ich angefangen habe, MoXAML Power Toys zu schreiben, um automatische Eigenschaften in Notify-Eigenschaften umwandeln zu können .

    
Pete OHanlon 15.03.2009 22:44
quelle