这个函数如何改变我的readonly变量?

时间:2011-10-19 08:43:15

标签: c# xmpp

我在C#中使用jabber.net并且有一个让我困惑的怪癖,所以希望有人可以解释它是如何做到的。从C ++背景来看,我对C#还是很陌生,所以这可能是一个误解

我正在创建一个只读JID来保存我需要输入的房间:

private readonly JID messagingRoomJID;

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

后来我想加入一个房间,这是我感到困惑的地方

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

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

但资源如何改变?变量是只读的,但也不应该通过const引用传递,所以它是如何被更新的呢?

看起来我可以做到这一点,但我不确定这是明智的:

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

5 个答案:

答案 0 :(得分:7)

它不会改变变量的值。变量的值只是一个引用。该参考文献与以前保持一致。

参考所引用的对象内的数据发生了变化。仅readonly修饰符 适用于您的变量 - 它没有说明对象本身的可变性。

区分引用和对象非常重要 - 有关详细信息,请参阅my article on the topic

答案 1 :(得分:3)

因为它正在更改readonly变量的属性,而只有根元素本身是只读的。

例如,

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
}

因此,我们可以在构造函数中更改 it 一次;但是在包含属性,暴露字段等的复杂类型的情况下,我们可以改变之后的那些。这就是为什么(对于一个常见的例子)具有readonly数组通常是一个坏主意,或者至少可以想象它通常不是预期的 - 因为数组的元素可以改变。

答案 2 :(得分:2)

所以,我认为Jon Skeet的回答是正确的。 例如,您的类变量 messagingRoomJID 是readonly和引用,因此您无法将其分配给新值,但您当然可以更改其所有属性的值,因为属性“Resource”不是只读。

GetRoom()方法调用不会更改内存中的messagingRoomJID变量引用,它只会更改其允许的某个属性的值。

答案 3 :(得分:1)

readonly表示不会更改对实例的引用。但是您可以更改此对象的任何字段。何时传递给方法GetRoom,它通过引用传递。因此GetRoom可以更改任何对象的字段。

答案 4 :(得分:0)

根据MSDN,只能在声明期间或使用构造函数初始化只读字段。

  

readonly字段可以在声明或构造函数中初始化。因此,readonly字段可以具有不同的值,具体取决于所使用的构造函数。

但是,在代码中,您在初始化期间或使用构造函数时不会更改,但属性Resource仍然包含值。

正如Jon Skeet所指出的,我会尝试添加它,引用类型变量的值为nullmemorry address

所以,当你声明:

private readonly JID messagingRoomJID;

此时messagingRoomJID是只读的,但该内存位置的属性很少,在这种情况下Resource可以更改为其他值。