Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How is this function changing my readonly variable?

Tags:

c#

xmpp

I am using jabber.net in C# and there is a quirk that has confused me so hopefully someone can explain how it is doing it. I am still quite new to C# from a C++ background so it may be a misunderstanding there

I am creating a readonly JID to hold a room that I need to enter:

private readonly JID messagingRoomJID;

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

Later I want to join a room which is where I get the thing I am confused by

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

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

But how is Resource being changed? The variable is readonly but also shouldn't it be passed by const reference, so how is it being updated anyway?

It looks like I can do it by this but I am not sure it is sensible:

theRoom = conferenceManager.GetRoom(new JID(messagingRoomJID));
like image 957
Firedragon Avatar asked Dec 12 '22 08:12

Firedragon


2 Answers

It's not changing the value of your variable. The value of your variable is just a reference. That reference is staying the same as it was before.

What's changing is the data within the object that the reference refers to. The readonly modifier only applies to your variable - it doesn't say anything about the mutability of the object itself.

It's very important to distinguish between references and objects - see my article on the topic for more information.

like image 144
Jon Skeet Avatar answered Dec 14 '22 20:12

Jon Skeet


Because it is changing a property of your readonly variable, whereas only the root element is readonly per se.

For instance,

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
}

So, we can change it once, in the constructor; but in the case of a complex type containing properties, exposed fields and such and so, we can alter those ever after. This is why (for a common example) having a readonly array is generally a bad idea, or at least conceivable that it often isn't what is intended - since the elements of the array can be changed.

like image 20
Grant Thomas Avatar answered Dec 14 '22 22:12

Grant Thomas