Eigenschaften - nach Wert oder Referenz?

7

Ich habe die folgende öffentliche Eigenschaft, die Arraylist verfügbar macht:

%Vor%

An anderer Stelle rufe ich an

%Vor%

Diese scheinen der privaten ArrayList _SpillageRiskDescriptions (über die Eigenschaft) Elemente hinzuzufügen, obwohl ich erwartet hätte, dass dies ein Problem verursacht. Daher bin ich richtig in der Annahme, dass Eigenschaften eine Referenz auf die ursprüngliche Variable zurückgeben und nicht durch value übergeben? Liegt das daran, dass ArrayList ein Referenztyp ist? Wird das gleiche mit einem int (zum Beispiel?)

passieren?     
m.edmondson 11.03.2011, 15:22
quelle

6 Antworten

9

Technisch ist es immer nach Wert, aber Sie müssen verstehen, was passiert ist. Da es sich um einen Referenztyp handelt, übergeben Sie eine Referenz zurück (aber nach Wert).

Ich hoffe, das macht Sinn. Sie geben das Ergebnis immer als Wert zurück, aber wenn es sich bei dem Typ um eine Referenz handelt, übergeben Sie die Referenz als Wert, was bedeutet, dass Sie das Objekt, aber nicht das Objekt, auf das es verweist, ändern können.

    
James Michael Hare 11.03.2011, 15:28
quelle
8

Die anderen Antworten haben Ihre primäre Frage korrekt beantwortet: dass der Wert einer Eigenschaft des Referenztyps eine Referenz für instance des Referenztyps.

Die größere Frage ist: "Was machst du jetzt?" Vermutlich wollen Sie nicht Code, der die Liste erhalten kann ändern .

Hier gibt es mehrere Möglichkeiten.

Erstens, egal, was Sie tun, ich empfehle, dass Sie jetzt aufhören, ArrayList zu verwenden und einen moderneren, sicheren Typ zum Speichern einer Liste von Dingen zu verwenden. List<string> kommt mir sofort in den Sinn.

Zweitens, muss der Setter der Eigenschaft öffentlich sein? Willst du nur, dass jemand diese Liste ändern kann? Oder sollte der Typ selbst für die Aktualisierung verantwortlich sein? Ich würde überlegen, den Setter privat zu machen.

Drittens haben wir eine kompaktere Syntax für eine "triviale" Eigenschaft. Du könntest sagen

%Vor%

und der Compiler wird das Hintergrundfeld für Sie generieren.

Beachten Sie, dass List<string> immer noch eine Mutation zulässt.

Wenn es für den Client wichtig ist, die Liste nacheinander zu durchlaufen, können Sie Folgendes tun:

%Vor%

und jetzt ist es für den Anrufer unmöglich, die Liste zu mutieren, weil alles, was Sie ihnen geben, ein Iterator ist, nicht der Zugriff auf die Liste selbst.

Oder Sie könnten tun:

%Vor%

Und jetzt hat der Aufrufer eine schreibgeschützte Ansicht der Liste, die eine Ausnahme auslöst, wenn sie versuchen, sie zu ändern.

    
Eric Lippert 11.03.2011 15:51
quelle
2

C # gibt Objekte als Referenz zurück.

Nur Dinge, die nicht als Wert zurückgegeben werden, sind:

Primitive Typen.
Struktypen.
Enums.

    
Yochai Timmer 11.03.2011 15:27
quelle
1

Es hat nichts damit zu tun, ob es eine Eigenschaft an sich ist; Es ist der Datentyp der Eigenschaft. In diesem Fall verwenden Sie ArrayList , eine Klasse, die als Referenz übergeben wird. Wenn die Eigenschaft als int eingegeben würde, würde sie als Wert übergeben.

    
Thomas 11.03.2011 15:26
quelle
0

Eine Eigenschaft ist eigentlich ein Paar von zwei Methoden - ein Setter und ein Getter. Sie übergeben den Wert des Hintergrundfelds (oder was auch immer als Quelle / Ziel verwendet wird) unverändert. Bei Referenztypen wird die Referenz übergeben und bei Werttypen wird der Wert übergeben.

%Vor%

Beachten Sie, dass Sie durch das Zuweisen einer ArrayList -Instanz zu Ihrer Eigenschaft im Prinzip die ArrayList -Instanz ersetzen, auf die das Hintergrundfeld zeigt.

Um Ihre speziellen Fragen zu beantworten:

  

Ich bin also der Ansicht, dass Eigenschaften eine Referenz an die ursprüngliche Variable zurückgeben und nicht an value übergeben?

Nein, mit dem Getter erhalten Sie keinen Verweis auf das Feld _SpillageRiskDescriptions . Sie erhalten den Wert des Feldes, der eine Referenz auf eine (dynamisch zugeordnete) ArrayList Instanz ist.

  

Liegt das daran, dass ArrayList ein Referenztyp ist?

Ja, ArrayList ist ein Referenztyp und Sie erhalten somit den Verweis auf die bestimmte ArrayList -Instanz.

  

Wird das gleiche mit einem int (zum Beispiel?)

passieren?

Ja und nein. Ja , Sie erhalten den Wert eines int -Feldes. Und no , int ist ein Werttyp. Wenn Sie also den Wert ändern, ohne ihn explizit zurückzusetzen, wird das zugrunde liegende Feld nicht beeinflusst.

    
Ondrej Tucny 11.03.2011 15:28
quelle
0

Es hat nichts mit der Eigenschaft zu tun.

In diesem Fall übergeben Sie einen Verweis auf die Array-Liste nach Wert.

Wenn Sie etwas wie

tun %Vor%

dann wird der Verweis auf die Array-Liste geändert.

Wenn du etwas wie

machen würdest %Vor%

dann würde der ursprüngliche Verweis auf die Array-Liste überhaupt nicht geändert werden.

Aber wenn Sie die Referenz als Referenz übergeben würden, wie in:

%Vor%

Dann würde Ihre Eigenschaft mit einer neuen Array-Liste mit einem einzelnen Element enden.

    
smartcaveman 11.03.2011 15:35
quelle