4 Stimmen

Wie verändert diese Funktion meine schreibgeschützte Variable?

Ich benutze jabber.net in C# und es gibt eine Eigenart, die mich verwirrt hat, so hoffentlich jemand erklären kann, wie es tut es. Ich bin immer noch ziemlich neu in C# von einem C + + Hintergrund, so kann es ein Missverständnis dort sein

Ich erstelle ein schreibgeschütztes JID, um einen Raum zu speichern, den ich betreten muss:

private readonly JID messagingRoomJID;

public MyClass
{
   // Reads from database but for purpose of this question
   messagingRoomJID = new JID("user@myserver");
}

Später möchte ich einem Raum beitreten, und da kommt das, was mich verwirrt

conferenceManager = new ConferenceManager();
conferenceManager.Stream = xmppClient;

// Before entering this room messagingRoomJID.Resource == null
theRoom = conferenceManager.GetRoom(messagingRoomJID);
// But now messagingRoomJID.Resource contains my username

Aber wie werden die Ressourcen verändert? Die Variable ist schreibgeschützt, aber sollte sie nicht auch per Konstantenreferenz übergeben werden, wie wird sie also überhaupt aktualisiert?

Es sieht so aus, als könnte ich es so machen, aber ich bin mir nicht sicher, ob das sinnvoll ist:

theRoom = conferenceManager.GetRoom(new JID(messagingRoomJID));

7voto

Jon Skeet Punkte 1325502

Der Wert der Variablen wird nicht geändert. Der Wert Ihrer Variablen ist nur ein Verweis. Dieser Verweis bleibt derselbe wie vorher.

Was sich ändert, sind die Daten innerhalb des Objekts, auf das sich der Verweis bezieht. Die readonly Modifikator sólo gilt für Ihre Variable - sie sagt nichts über die Veränderbarkeit des Objekts selbst aus.

Es ist sehr wichtig, zwischen Referenzen und Objekten zu unterscheiden - siehe mein Artikel zu diesem Thema für weitere Informationen.

3voto

Grant Thomas Punkte 43318

Denn sie verändert eine Eigenschaft Ihrer readonly Variable, während nur das Element Root per se schreibgeschützt ist.

Zum Beispiel,

private readonly int MyReadOnlyVariable;
private readonly ComplexType MyReadOnlyComplexType;

public MyClass()
{
    MyReadOnlyVariable = 2;            //valid
    MyReadOnlyComplexType = something; //valid
}

public void NotAConstructor()
{
    MyReadOnlyVariable = 2;                          //invalid
    MyReadOnlyComplexType = somethingElse;           //invalid
    MyReadOnlyComplexType.Something = somethingElse; //valid
}

Wir können also ändern es einmal, im Konstruktor; aber im Falle eines komplexen Typs mit Eigenschaften, exponierten Feldern und so weiter und so fort, müssen wir kann diese für immer zu ändern. Aus diesem Grund ist (als allgemeines Beispiel) eine readonly Array ist im Allgemeinen eine schlechte Idee, oder zumindest denkbar, dass es oft nicht das ist, was beabsichtigt ist - da die Elemente des Arrays geändert werden können.

2voto

VSS Punkte 7962

Daher halte ich die Antwort von Jon Skeet für richtig. Ein Beispiel: Ihre Klassenvariable messagingRoomJID ist schreibgeschützt und ein Verweis, so dass Sie ihm keinen neuen Wert zuweisen können, aber Sie können natürlich die Werte aller seiner Eigenschaften ändern, da die Eigenschaft "Ressource" nicht schreibgeschützt ist.

Der Aufruf der Methode GetRoom() ändert nicht den Verweis auf die Variable messagingRoomJID im Speicher, sondern nur den Wert einer ihrer Eigenschaften, was zulässig ist.

1voto

kyrylomyr Punkte 11484

readonly bedeutet, dass der Verweis auf die Instanz nicht geändert wird. Sie können aber jedes Feld dieses Objekts ändern. Wenn an die Methode übergeben wird GetRoom wird es als Referenz übergeben. Also GetRoom kann das Feld eines beliebigen Objekts ändern.

0voto

Simsons Punkte 11743

Gemäß MSDN Readonly-Felder können bei der Deklaration oder mit Hilfe eines Konstruktors initialisiert werden.

Ein schreibgeschütztes Feld kann entweder bei der Deklaration oder in einem Konstruktor initialisiert werden. Daher können Readonly-Felder je nach dem verwendeten Konstruktor unterschiedliche Werte haben.

Da Sie in Ihrem Code jedoch weder während der Initialisierung noch mit einem Konstruktor die Eigenschaft Resource enthält den Wert.

Wie von Jon Skeet hervorgehoben, würde ich versuchen, dem hinzuzufügen, dass der Wert einer Variablen vom Typ Referenz entweder null oder eine memorry address .

Also, wenn Sie erklären:

private readonly JID messagingRoomJID;

Zu dieser Zeit messagingRoomJID ist schreibgeschützt, aber es sind nur wenige Eigenschaften an diesem Speicherplatz vorhanden, in diesem Fall Resource kann auf einen anderen Wert geändert werden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X