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.