Ссылочные типы C#

Попалась интересная задачка по C#, не могу понять, почему после функции Find(Checker Check1) значение Check1 = 11. Объясните подробно, пожалуйста.

class Program
{
  static void Main(string[] args)
  {
    Console.WriteLine(Calculate().ToString());
    Console.ReadKey();
  }
  static void Find(Checker Check1)
  {
    Check1.Count += 10;
    var Check2 = new Checker();
    Check2.Count = Check1.Count;
    Check2.Count += 100;
    Check1 = Check2;
  }
  static void Find(ref Checker Check1)
  {
    Check1.Count += 1000;
    var Check2 = new Checker();
    Check2.Count = Check1.Count;
    Check2.Count += 10000;
    Check1 = Check2;
  }
  static void FindSimple(CheckerSimple Check1)
  {
    Check1.Count += 30;
    CheckerSimple Check2;
    Check2.Count = Check1.Count;
    Check2.Count += 300;
    Check1 = Check2;
 }
 static void FindSimple(ref CheckerSimple Check1)
 {
   Check1.Count += 300;
   CheckerSimple Check2;
   Check2.Count = Check1.Count;
   Check2.Count += 3000;
   Check1 = Check2;
 }
 static public int Calculate()
 {
   var Check1 = new Checker();
   Check1.Count += 1;
   Find(Check1);
   Find(ref Check1);
   CheckerSimple Check2;
   Check2.Count = Check1.Count;
   FindSimple(Check2);
   FindSimple(ref Check2);
   return Check2.Count;
 }
}
class Checker
{
  int count;
  public int Count
  {
    get { return count; }
    set { count = value; }
  }
  public Checker()
  {
    Count = 0;
  }
}
struct CheckerSimple
{
  public int Count;
}

Ответы (1 шт):

Автор решения: Alex Krass

Функции хранят свои собственные параметры в своём стеке и поэтому надо понимать, что это разные переменные и ведут они себя соответственно. Когда вы вызываете Find, то переменные Main.Check1 и Find.Check1 указывают на одну область памяти.

введите сюда описание изображения

Если вы перезаписали ссылку на объект в памяти в переменной Find.Check1, то она будет указывать на новый объект, а вот Main.Check1 на старый. Это суть ссылочных типов, когда меняются ссылки на объект в переменной. Поэтому ваш объект и хранит значение Heap.Check1 = 11. В то время как в Heap.Check2 будет ваше значение 1000.

введите сюда описание изображения

Пометив параметр как ref вы грубо говоря связываете переменные, поэтому в остальных функциях из-за этого будут перезаписывать ссылки не только в Find.Check1, но и в Main.Check1.

введите сюда описание изображения

→ Ссылка