2015-09-12 56 views
0

这真是困惑我...变量设置为相同的值?

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 = data'时,t2等于4,但t1也是如此在这段代码t1的末尾,t2和t3等于t4,但它们都应该是唯一的。为什么是这个,我该如何解决它?

+4

t1,t2,t3和t4的数据类型是什么?你也可以显示你的receive()方法吗? – displayName

+0

是的,有趣的是什么是数据类型的t1等,如果这些是值类型,这不应该发生 –

+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. 

最后,它真的取决于你想要完成的。如果你想要更具体些,我可以举一个例子。

希望这是有道理的。

+0

对不起,我看到'带有值类型,对象和它的数据存储在堆栈内存中后,没有看到你的答案'http://stackoverflow.com/questions/1932155/why-value-types-are-stored-进入堆栈 – Eser

+0

伟大的增加。他们是对的。 Eric Lippert和Marc Gravel是天才! – bjhuffine

+0

@Eser我试着更新它,但很快。如果您发现任何问题,请告知我,我很乐意纠正它。但也许这样我可以尝试做到这一点,但也更具体。 – bjhuffine

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都将能够“看到”它,因为像提到它们都指向同一个对象:someObject。这种情况与引用类型在C#,而不是与值类型,如intchar

更多reading

+0

什么是'reference'? – Eser

+0

@Eser:你是什么意思? –

+0

'var2 = reference;' – Eser