C# 变量是否将彼此设置为相同的值?

C# 变量是否将彼此设置为相同的值?,c#,variables,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 th

这真让我困惑

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

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

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
都将能够“看到”它,因为正如前面提到的,它们都指向同一个对象:
someObject
。这种情况发生在C#中的引用类型上,而不是像
int
char
等值类型上


更多

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

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
都将能够“看到”它,因为正如前面提到的,它们都指向同一个对象:
someObject
。这种情况发生在C#中的引用类型上,而不是像
int
char
等值类型上


更多

更新:为了更具体、更不含糊,并结合Eser提供的正确参考信息,我想我会编辑此内容。希望这会更清楚

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

值类型是int、enum、decimal、bool、structs等类型。它们有时存储在堆栈内存中。这是CLR如何分配对象数据的实现细节,可能并不总是正确的。这些类型的要点是它们是“按值复制的”。当您将其作为参数传递给方法时,可以说明这一点,值类型复制到堆栈中,复制的版本在方法中使用。这允许两个值(正在传递的值和方法中的值)不同。如果方法参数使用ref关键字,则此图的例外情况。当然,也有例外,这并不总是黑白分明的。如果对象是一个类的字段,那么它将与其他引用数据(下面描述的引用类型)一起存储在堆上,并且由于捕获的变量封装在lambda的表达式树对象(引用类型)中,因此它们也将存储在堆上。但是,对于一个基本的理解,考虑这是一个对象,它的值在传递到另一个值时被分配到堆栈上,因为它是由值复制的。p> 引用类型不同。对象数据存储在堆内存中,而对数据的引用存储在堆栈中。引用是一个包含地址和其他特性的对象,这些特性允许它有效地引用堆上的数据。这意味着,如果将对象传递给方法参数,它只会从堆栈中复制引用,而堆栈仍然指向堆上的对象数据。因此,如果您的方法更改了其对象值,那么它将影响堆上存储这些值的唯一位置。因此,传递给方法的初始值和方法中的值都是相同的。在开发过程中,我们经常利用这一点来发挥我们的优势,但您必须认识到这一点。引用类型的示例有类、字符串、对象等

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

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


希望这是有意义的。

更新:为了更具体一点,不那么含糊,并结合Eser提供的正确参考信息,我想我会编辑这篇文章。希望这会更清楚

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

值类型是int、enum、decimal、bool、structs等类型。它们有时存储在堆栈内存中。这是CLR如何分配对象数据的实现细节,可能并不总是正确的。这些类型的要点是它们是“按值复制的”。当您将其作为参数传递给方法时,可以说明这一点,值类型复制到堆栈中,复制的版本在方法中使用。这允许两个值(正在传递的值和方法中的值)不同。如果方法参数使用ref关键字,则此图的例外情况。当然,也有例外,这并不总是黑白分明的。如果对象是一个类的字段,那么它将与其余的引用数据(下面描述的引用类型)一起存储在堆上,并且自捕获变量