2
    public void MethodSample1(Itest variable)
    {
        variable.TestString = "some sample data";
        Itest var1 = variable;
        Console.WriteLine(variable.TestString);
        MethodSample2(variable);
        Console.WriteLine(variable.TestString);
        Console.WriteLine(var1.TestString);

    }

    public void MethodSample2(Itest variable)
    {
        variable.TestString = "testdata";
    }

    public interface Itest
    {
      string TestString { get; set; }
    }

Expected both the console output lines print "some sample data" but it seems that TestString is being overwritten with the new value? is it not like "by default in C# all the values are passed by value?".

In short, how to preserve the value of "TestString" in MethodSample1?

(I ran into this problem because all my projects are based upon a single interface)

Even after preserving the value, it does reflect! strange!

3 Answers3

5

For your current problem, I don't think you can prevent any method from modifying the parameter passed to it.

Your variable is a reference type object, In C# reference type's address is passed by value to a method, that is why you are seeing the change. For example if your method is written like:

public void MethodSample2(Itest variable)
{
    variable = null;
}

You won't see the change in your MethodSample1 method, since the reference address is passed by value.

is it not like "by default in C# all the values are passed by value?".

Value types are passed by value, in your case variable is a reference type.

You should see Parameter Passing C# by Jon Skeet

Not sure why you have to modify the passed object, For workaround you can create a temporary copy of the property and then set that value before existing from the method.

Habib
  • 219,104
  • 29
  • 407
  • 436
  • Thanks Habib for "your variable is a reference type object". But, i tried to preserve my variable. Even then it doesnot help! please see my updated question. – now he who must not be named. Jan 09 '13 at 09:46
  • 2
    @nowhewhomustnotbenamed., the way you are preserving it, it is again copying the reference to new variable `var1`. You need to Clone it, or in simple words create a completely new copy of the variable. You have shallow copy currently. You need deep copy, see: http://stackoverflow.com/questions/184710/what-is-the-difference-between-a-deep-copy-and-a-shallow-copy – Habib Jan 09 '13 at 09:49
  • @nowhewhomustnotbenamed., you may see: http://stackoverflow.com/questions/129389/how-do-you-do-a-deep-copy-an-object-in-net-c-specifically – Habib Jan 09 '13 at 10:05
2

The parameter is indeed passed by value, but the value you are passing is a reference to the original object.

If you want to preserve the original object's properties, you'll need to pass a copy of the original object. You could add a Clone() method to the interface or something similar:

public interface ITest
{
    string TestString { get; set; }
    ITest Clone();      
}

public class Test : ITest 
{
    string TestString { get; set; }
    ITest Clone() { 
        return new Test() { 
            TestString = this.TestString 
        }; 
    }
}

Or, you could rethink your current approach. Do you really need to change the property of the interface? Or could you use a variable of type string instead?

Botz3000
  • 39,020
  • 8
  • 103
  • 127
  • yes exactly what I want.. but how exactly do I "you'll need to pass a copy of the original object." ? – now he who must not be named. Jan 09 '13 at 09:40
  • @nowhewhomustnotbenamed. How you copy the object is a different matter. You could add ICloneable to your interface (or add a Clone() method to it) which would require implementors of your interface to be able to clone themselves. Or, you could rethink your current approach. Do you really need to change the property of the interface? Or could you use a variable of type string instead? – Botz3000 Jan 09 '13 at 09:41
  • Thanks Botz.. But, I have a method that accepts this interface in my project(sorry could not post the real samples, its pretty huge!).. So, I need to call the method(twice with different inputs) with the interface members but preserve the original one. Can u give me some code examples for IClone ? Thanks for letting me know that! – now he who must not be named. Jan 09 '13 at 09:50
  • 1
    @nowhewhomustnotbenamed. It's quite simple, just create a new instance and copy all properties. See the edit in my answer. – Botz3000 Jan 09 '13 at 10:05
1

how to preserve the value of "TestString" in MethodSample1?

Store it in a local variable.

public void MethodSample1(Itest variable)
{
    variable.TestString = "some sample data";
    string localTestString = variable.TestString;

    Console.WriteLine(variable.TestString);

    MethodSample2(variable);
    variable.TestString = localTestString;

    Console.WriteLine(variable.TestString);

}

But, this is wrong way of doing things. If you tell a little more what do you want to achieve, we could help more.

Azodious
  • 13,752
  • 1
  • 36
  • 71