这让我很困惑......
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变量。 “接收”方法会改变“数据”的含义。
当我使用断点运行代码时,我可以看到t1 = 1。然后当它达到't2 = data't2然后等于4但t1也是如此?在这个片段t1的末尾,t2和t3等于t4,但它们都应该是唯一的。为什么这样,我该如何解决?
答案 0 :(得分:3)
这可能是由于引用语义造成的。 假设你引用了一些对象
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
的值,var1
和var2
都将能够“看到”它,因为如上所述,它们都指向同一个对象:{{ 1}}。这种情况发生在C#中的引用类型中,而不是someObject
,int
等值类型。
更多reading
答案 1 :(得分:1)
更新:为了更具体,更不含糊,并结合Eser提供的正确引用信息,我想我会编辑它。希望这会更清楚。
这可能不是问题。发生了什么是数据属于参考类型。有两种数据类型,引用和值类型。它们的运作方式不同,了解它们的生命周期也很重要。
值类型是int,enum,decimal,bool,structs等类型。它们有时存储在堆栈内存中。这是CLR如何分配对象数据的实现细节,可能并非总是如此。这些类型的要点是它们被价值"复制。将此作为参数传递给方法时,可以说明这一点,将值类型复制到堆栈中,并在方法中使用复制的版本。这允许两个值(传递的值和方法中的值)不同。此插图的例外情况是方法参数是否使用ref关键字。当然,也有例外,这并不总是黑白分明。如果对象是类的字段,那么它将与其余的引用数据(下面描述的引用类型)一起存储在堆上,并且由于捕获的变量被封装在lambda的表达式树对象(引用类型)中,然后它们也将存储在堆上。但是为了基本的理解,请考虑这个对象,当传递给另一个值时,它的值在堆栈上分配,因为它是按值复制的。
参考类型不同。对象数据存储在堆内存中,而对数据的引用存储在堆栈中。引用是一个包含地址和其他功能的对象,允许它有效地引用堆上的数据。这意味着如果将对象传递给方法参数,它只会从堆栈中创建一个仍然指向堆上对象数据的引用的副本。因此,如果您的方法更改其对象值,则它会影响堆上存储这些值的唯一位置。因此,传递给方法的初始值以及方法中的值都是相同的。在开发过程中,我们使用它对我们有利,但你必须认识它。引用类型的示例是类,字符串,对象等。
因此,在您的情况下,t1包含与t2,t3和t4相同的引用类型地址。因此,每当方法更改数据时,它也会更改这些数据。你是如何解决这个问题的?不要在数据中使用单独的变量'如果你需要做什么,检查它的状态。如果'数据'应该是不同的,然后它听起来像是重新使用它传递的值而不是重新创建一个新对象。由于它重复使用引用类型的结果对象,因此它保持您的tx变量相同。如果是这种情况,并且您想要不同的结果,那么它的数据就是'结果应该由新实例化的对象反映出来。也许就像... ...
data= Receive(i); //Where Receive() returns a newly instantiated object.
最后,它实际上取决于你想要完成的事情。如果你想更具体一点,我可以提供一个例子。
希望这是有道理的。