Как передать ссылку на константу в С#?

В С++ передача ссылок const является обычной практикой - например:

#include <iostream>
using namespace std;

class X
{
  public :
    X()                              {m_x = 0; }
    X(const int & x)                 {m_x = x; }
    X(const X & other)               { *this = other; }
    X & operator = (const X & other) { m_x = other.m_x; return *this; }
    void print()                     { cout << m_x << endl; }
  private :
    int m_x;
};

void main()
{
    X x1(5);
    X x2(4);
    X x3(x2);
    x2 = x1;
    x1.print();
    x2.print();
    x3.print();
}

Этот простой пример иллюстрирует, как это делается - в значительной степени. Однако я заметил, что в С# это, похоже, не так. Должен ли я передавать ссылки const в С#? для чего мне нужно ключевое слово "ref"? Обратите внимание, что я знаю и понимаю, что такое ссылочные и ссылочные типы С#.

Ответ 1

С# не имеет понятия объектов const (т.е. объектов, которые вы не можете изменить); только переменные (т.е. поля) могут быть const или readonly - это означает, что вы не можете назначить их.

Ключевое слово ref концептуально передает ссылку на переменную в качестве параметра, то есть вызывающий может изменять переменную (а не просто изменять значение). Это особенно полезно для примитивных типов (int, bool и т.д.).

Ответ 2

ответить на часть ответа на ваш вопрос; когда вы передаете переменную методу, создается копия этой переменной. Использование ключевого слова ref передаст тот же экземпляр этой переменной, чтобы метод мог обновить эту переменную для вызывающего.

Многие считают, что это относится только к типам значений, потому что ссылочные типы просто передаются как ссылка, так что ключевое слово ref не имеет никакого эффекта. Однако это неверно, эта ссылка передается методу так же, как значение; он копируется и создается новый экземпляр этой ссылки. Это означает, что вызывающий объект будет видеть изменения самого объекта, но не ссылки. Итак, если вы попытались установить объект в null или новый объект, вызывающий объект не увидит эту модификацию, если ключевое слово ref не используется:

Без ссылки:

void UpdatePerson(Person person)
{
   // Caller would see this change
   person.Name = "Bob";
   // Caller wouldn't see this change
   person = null;
}

С помощью ссылки

void UpdatePerson(ref Person person)
{
   // Caller would see this change
   person.Name = "Bob";
   // Caller would see this change
   person = null;
}