变量是否相互设置为相同的值?

时间:2015-09-12 19:53:36

标签: c# variables

这让我很困惑......

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,但它们都应该是唯一的。为什么这样,我该如何解决?

2 个答案:

答案 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的值,var1var2都将能够“看到”它,因为如上所述,它们都指向同一个对象:{{ 1}}。这种情况发生在C#中的引用类型中,而不是someObjectint等值类型。

更多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.

最后,它实际上取决于你想要完成的事情。如果你想更具体一点,我可以提供一个例子。

希望这是有道理的。