0

I have some code that downloads data into a class for storage and then creates a copy of that class to pass into a method that alters the data. Somehow my original class is also being altered and I'm not sure what I'm doing wrong.

Calculations calc = new Calculations(Symbol, Market);
calc.stockData = loadData(Symbol, Market);
for (int j = calc.stockData.Count - 8; j >= 0; j--)
                    {
                        highPrice = 0;

                        // 0 newest
                        // as you go higher in the index, it is older
                        for (int k = j + 1; k < j + 8; k++)
                        {
                            kIndex = k;
                            jIndex = j;
                            decimal highRiskCurrentHigh = Calculations.calculateReturnPercentageStatic(calc.stockData.ElementAtOrDefault(k).Close,
                                calc.stockData.ElementAtOrDefault(j).High);

                            if (highRiskCurrentHigh > highPrice)
                            {
                                highPrice = highRiskCurrentHigh;
                                highIndex = k;
                            }
                        }

                        Test test = new Test();
                        test.returnPct = highPrice;
                        test.date = calc.stockData.ElementAtOrDefault(highIndex).Date;
                        test.symbolClass = symbolsList.ElementAtOrDefault(i);
                        Calculations copy = calc;
                        test.ratingClass = performCalculations(test.symbolClass, copy, test.date); // passing a copy into the method for altering
                        stuffList.Add(test); // inserted a breakpoint here and the original class (calc) has been altered
                    }
DarthVegan
  • 1,719
  • 7
  • 25
  • 42

3 Answers3

5

This code does not create a copy:

Calculations copy = calc;

In C# objects all exist on the heap and are manipulated through references, compare to C++ where you can create objects on the stack and assignment is equal to a copy operation.

Instead, implement IClonable and provide your own copy operation.

Dai
  • 141,631
  • 28
  • 261
  • 374
  • 2
    Microsoft no longer recommends using the ICloneable interface. See the "[Notes to Implmenters](https://msdn.microsoft.com/en-us/library/system.icloneable(v=vs.110).aspx)" section of the documentation. *"[The ICloneable interface] does not specify whether the cloning operation performs a deep copy, a shallow copy, or something in between. [...] Because callers of Clone cannot depend on the method performing a predictable cloning operation, we recommend that ICloneable not be implemented in public APIs."* – Scott Chamberlain Mar 16 '15 at 19:31
3
Calculations copy = calc;

is not creating a copy of your original data it is a reference to the same data. You need to clone this data.

More info on how to clone can be found here :

Deep cloning objects

Community
  • 1
  • 1
Philip Stuyck
  • 7,344
  • 3
  • 28
  • 39
3

Let's walk through your code so you understand what is happening here. (What you are telling your code to do is written in the comments.)

// 1. create a new instance of the object 'Calculations' on the heap
// 2. return the memory address of that instance and assign it to variable 'calc'
Calculations calc = new Calculations(Symbol, Market);

// 3. Create a variable called 'copy' that points to 'Calculations' type objects
// 4. Assign the value of 'calc' (which is a reference to the heap object) to 'copy'
Calculations copy = calc;

Simply put, in your code calc and copy are pointing to the same object in memory. That is why changes to copy are affecting calc. What you need to do is clone your object so that you have a new object that is equal in value but separate in memory.

Ian R. O'Brien
  • 6,682
  • 9
  • 45
  • 73
  • Thanks for explaining this for me! I will mark this as the answer soon – DarthVegan Mar 16 '15 at 19:33
  • 1
    @user3610374 You're welcome! You may want to read this article that is helpful for explaining how variables and reference/value types work in C# http://www.yoda.arachsys.com/csharp/parameters.html and http://www.yoda.arachsys.com/csharp/memory.html. – Ian R. O'Brien Mar 16 '15 at 21:05