Why do c# objects once behave like passed by value and once as passed by reference?

I don't understand one thing about passing parameters to methods in c#. From what I see objects in c# sometimes behave like the have been passed by reference and once as if they were passed by value. In this code I pass to method() one by reference and once by value. Both of these execute as expected. But when I created Update() and pass an object by value I see it behaving like it is updating original object.

Why do I update original object with Update(myString input) but do not update it with method(myString input)?

This is illogical!

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ClassPassing
{
class Program
{
    static void Main(string[] args)
    {
        myString zmienna = new myString();

        Update(zmienna);
        Console.WriteLine(zmienna.stringValue);
        Console.WriteLine(zmienna.stringValue2);
        Console.ReadLine();

        zmienna.stringValue = "This has run in main";
        zmienna.stringValue2 = "This is a help string";

        method(zmienna);
        Console.WriteLine(zmienna.stringValue);
        Console.WriteLine(zmienna.stringValue2);
        Console.ReadLine();

        method(ref zmienna);
        Console.WriteLine(zmienna.stringValue);
        Console.WriteLine(zmienna.stringValue2);

        Console.ReadLine();
    }

    static void method(myString input)
    {
        input = new myString();
    }

    static void method(ref myString input)
    {
        input = new myString();
    }

    static void Update(myString input)
    {
        input.stringValue2 = "This has run in update method";
    }
}

public class myString
{
    public string stringValue { get; set; }
    public string stringValue2 { get; set; }

    public myString() { stringValue = "This has been just constructed";   this.stringValue2 = "This has been just constructed"; }
}

}`

Jon Skeet
people
quotationmark

Objects aren't passed at all.

For expressions of a reference type (classes, interfaces etc) references are passed - by value by default, but the variables are passed by reference if you use ref.

It's important to understand that the value of zmienna isn't an object - it's a reference. Once you've got that sorted, the rest becomes simple. It's not just for parameter passing either - it's for everything. For example:

StringBuilder x = new StringBuilder();
StringBuilder y = x;
y.Append("Foo");
Console.WriteLine(x); // Prints Foo

Here the values of x and y are references to the same object - it's like having two pieces of paper, each of which has the same street address on. So if someone visits the house by reading the address written on x and paints the front door red, then someone else visits the same house by reading the address written on y, that second person will see a red front door too.

See my articles on reference and value types and parameter passing for more details.

people

See more on this question at Stackoverflow