这个函数如何改变我的只读变量

本文关键字:改变 我的 只读 变量 函数 何改变 | 更新日期: 2023-09-27 18:11:54

我在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));

这个函数如何改变我的只读变量

它没有改变变量的值。变量的值只是一个引用。这个引用和之前是一样的。

改变的是引用所指向的对象内的数据。readonly修饰符适用于您的变量-它没有说明任何关于对象本身的可变性。

区分引用和对象非常重要——更多信息请参阅我的文章。

因为它正在更改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数组通常是一个坏主意,或者至少可以想象它通常不是预期的-因为数组的元素可以改变。

所以,我认为Jon Skeet的答案是正确的。例如,你的类变量messagingRoomJID是只读的,并且是一个引用,所以你不能给它分配一个新值,但是你当然可以改变它所有属性的值,因为属性"Resource"不是只读的。

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

readonly表示对实例的引用不会被更改。但是你可以改变这个对象的任何字段。当传递给方法GetRoom时,它是通过引用传递的。所以GetRoom可以改变任何对象的字段

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

只读字段既可以在声明中初始化,也可以在构造函数中初始化。因此,只读字段可以有不同的值,这取决于所使用的构造函数。

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

正如Jon Skeet指出的那样,我将尝试添加到它,引用类型变量的值是nullmemorry address

所以,当你声明:

private readonly JID messagingRoomJID;

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