变量相互设置相同的值

本文关键字:设置 变量 | 更新日期: 2023-09-27 18:12:25

这真的让我很困惑…

t1 = data;//adds the recieved data to the variable
            read = false;//this tells IR 
            Console.WriteLine("Press " + name + " again (" + (2) + "/8)");
            recieve();
            t2 = data;//adds the recieved data to the variable
            read = false;//this tells IR 
            Console.WriteLine("Press " + name + " again (" + (3) + "/8)");
            recieve();
            t3 = data;//adds the recieved data to the variable
            read = false;//this tells IR 
            Console.WriteLine("Press " + name + " again (" + (4) + "/8)");
            recieve();
            t4 = data;//adds the recieved data to the variable
            read = false;//this tells IR 

这是我的脚本的一部分,问题是与t1, t2, t3,t4变量。方法'receive'改变了'data'是什么。

当我运行带有断点的代码时,我首先可以看到t1=1。然后当它达到't2=数据't2然后等于4,但t1也是??在这段代码的末尾,t1、t2和t3都等于t4,但它们都应该是唯一的。为什么会这样,我该如何解决?

变量相互设置相同的值

这可能是由于引用语义。假设你引用了某个对象

SomeClass var1 = someObject; // "var1" points to someObject, holds its address, not the value
// Now you copy that address to a different variable
// and end up with two references to the same object: someObject
SomeClass var2 = var1; // now var2 also "points" to someObject

如果之后改变someObject的值,var1var2都能"看到"它,因为它们都指向同一个对象:someObject。这发生在c#中的引用类型,而不是值类型,如int, char等。

更多阅读

Updated:为了更具体,更不模糊,并与Eser提供的正确参考信息相结合,我想我会编辑这个。希望这能更清楚。

这可能不是问题。这里的数据是引用类型。有两种数据类型:引用类型和值类型。它们的运作方式不同,了解它们的生命周期很重要。

值类型包括int、enum、decimal、bool、structs等类型。它们有时存储在堆栈内存中。这是CLR如何分配对象数据的实现细节,可能并不总是正确的。这些类型的主要特点是它们是"按值复制"的。当您将This作为参数传递给方法时,可以说明这一点,值类型被复制到堆栈中,并且复制的版本在方法中使用。这允许两个值(传递的值和方法中的值)不同。这个例子的例外情况是方法参数使用ref关键字。当然,也有例外,这并不总是非黑即白的。如果对象是一个类的字段,那么它将与其他引用数据(下面描述的引用类型)一起存储在堆上,并且由于捕获的变量被封装在lambda的表达式树对象(引用类型)中,因此它们也将存储在堆上。但是为了获得基本的理解,可以把它看作一个对象,它的值在传递给另一个值时在堆栈上分配,因为它是按值复制的。

引用类型不同。对象数据存储在堆内存中,而对数据的引用存储在堆栈中。引用是一个对象,它包含地址和其他允许它有效地引用堆上的数据的特性。这意味着,如果你将对象传递给方法参数,它只会从堆栈中复制引用,该引用仍然指向堆上的对象数据。因此,如果您的方法更改了它的对象值,那么它将影响堆上存储这些值的唯一位置。所以传递给方法的初始值和方法中的值都是一样的。在开发过程中,我们经常利用这一点,但你必须认识到这一点。引用类型的例子有类、字符串、对象等。

所以在你的例子中,t1包含与t2, t3和t4相同的引用类型地址。每次方法改变data时,它也会改变那些。如何解决这个问题?如果需要的话,不要为"data"使用单独的变量并检查它的状态。如果"data"应该是不同的,那么它听起来像是在重用它传递的值,而不是重新创建一个新对象。因为它重用了引用类型的结果对象,所以它使tx变量保持不变。如果是这种情况,你想要不同的结果,那么它的'data'结果应该由一个新实例化的对象反映。

data= Receive(i);  //Where Receive() returns a newly instantiated object.
最后,这真的取决于你想要完成什么。如果你想更具体一点,我可以提供一个例子。