0

This is really confusing me...

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 

This is part of my script, the issue is with the t1, t2, t3 ,t4 variables. The method 'receive' changes what 'data' is.

When I run the code with breakpoints I can see that t1=1 at first. Then when it reaches 't2=data' t2 then equals 4 but so does t1??? by the end of this snippet t1, t2 and t3 are equal to t4 but they should all be unique. Why is this and how do I fix it?

Joe Speers
  • 43
  • 7
  • 4
    What's the data type of t1, t2, t3 and t4? Can you also show your receive() method? – displayName Sep 12 '15 at 19:59
  • yeah, interesting what's data type of t1, etc. if those are value types, this should not be happening – Giorgi Moniava Sep 12 '15 at 20:12
  • 1
    "Come up with rest of the code to achieve particular behavior" kind of questions are generally hard to answer (also entertaining) - please instead try to provide complete (but small) code that demonstrates problem and ask why it happens. – Alexei Levenkov Sep 12 '15 at 20:32

2 Answers2

3

This happens probably due to reference semantics. Say you have reference to some object

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

If you change value of someObject afterwards, var1 and also var2 will both be able to "see" it, because like mentioned they both point to the same object: someObject. This happens with reference types in C#, not with value types like int, char, etc.

More reading

Giorgi Moniava
  • 27,046
  • 9
  • 53
  • 90
1

Updated: In order to be a bit more specific and less vague and in conjunction with the correct referenced information that Eser provided, I thought I would edit this. Hopefully this will be more clear.

This may not be a problem. What's going on is that the data is of a reference type. There are two data types, reference and value types. They operate differently and it's important to understand their life cycle.

Value types are types like int, enum, decimal, bool, structs, etc. They are stored in stack memory sometimes. This is an implementation detail in how the CLR will allocate the object data and may not always be true. The main point of these types is that they are "copied by value". This can be illustrated when you pass this as an argument to a method, the value type is copied onto the stack and the copied version is used in the method. This allows the two values (the one being passed and the one in the method) to be different. The exception to this illustration would be if the method parameters used the ref keyword. Of course, there are exceptions and this is not always black and white. If the object is a field of a class then it gets stored on the heap with the rest of the reference data (reference type described below) and since captured variables are encapsulated in the expression tree objects (reference types) of a lambda, then they too will be stored on the heap. But for a basic understanding, consider this an object whose value is allocated on the stack when passed to another value because it is copied by value.

Reference types are different. The object data is stored on the heap memory while the reference to the data is stored on the stack. The reference is an object containing the address and other features that allow it to effectively reference its data on the heap. What this means is that if you pass the object to a method argument, it is only going to make a copy of the reference from the stack which is still pointing to the object data on the heap. Therefore, if your method changes its object values, then it is affecting the one and only location on the heap where these values are stored. So both the initial value passed to the method as well as the value in the method are the same. In development we use this a lot to our advantage, but you do have to be cognizant of it. Examples of reference types are classes, strings, object, etc.

So in your case t1 contains the reference type address the same as t2, t3, and t4. So every time the method changes 'data', it's changing those as well. How do you fix this? Don't use separate variables for 'data' and check its state if that's what you need to do. If 'data' is supposed to be different, then it sounds like it is re-using the value it is passing rather than recreating a new object. Since it's re-using the result object of a reference type, it's keeping your tx variables the same. If that's the case and you want different results, then it's 'data' result should be reflected by a newly instantiated object. Maybe something along the lines of...

data= Receive(i);  //Where Receive() returns a newly instantiated object.

In the end, it really depends on what you're trying to accomplish. If you want to be a bit more specific, I can probably provide an example.

Hope this makes sense.

bjhuffine
  • 924
  • 1
  • 11
  • 23
  • Sorry I didn't read your answer after I saw `With value types, the object and its data is stored in stack memory` http://stackoverflow.com/questions/1932155/why-value-types-are-stored-onto-stacks – Eser Sep 12 '15 at 20:40
  • Great addition. They're right about that. Eric Lippert and Marc Gravel are geniuses! – bjhuffine Sep 12 '15 at 20:43
  • @Eser I tried updating it, though quickly. Let me know if you see anything off point and I'll gladly correct it. But maybe this way I can try to be to the point but more specific too. – bjhuffine Sep 12 '15 at 21:28
  • 1- A wall of text is hard to read; to be honest I don't think much users will read it. 2- Here is sunday now, and my table is full of empty beer bottles. – Eser Sep 12 '15 at 21:41