Чтобы код, подобный этому, работал на C ++, вы обычно должны предоставить конструктор копирования для класса Widget. Копирование объектов в C ++ довольно распространено, это часто требуется, если вы храните объекты в коллекции. Это, однако, источник ужасных ошибок повреждения кучи, конструктор копирования по умолчанию, реализованный компилятором, не всегда подходит. Это псевдонимы указателей, копируя значение указателя вместо указанного значения. Мелкая копия вместо глубокой. Это плохо работает, когда деструктор класса удаляет указанный объект, как и должно быть, оставляя указатель в копии, указывающий на мусор.
Язык C # не имеет такого поведения, он не реализует конструктор копирования. В любом случае это очень редко требуется, сборщик мусора избегает необходимости делать копии. Очень заметен в любом тесте на коллекционных классах.
Вы, конечно, можете создать свой собственный конструктор копирования, вам просто нужно реализовать его явно:
void Widget(Widget other) {
this.X = other.X;
// etc...
}
И создайте копию явно:
Widget w = new Widget();
w.X = 42;
// etc...
foo(new Widget(w));
Что, возможно, также проясняет, что создание этих копий имеет ненулевую стоимость. Если вы хотите, чтобы виджет имел поведение значения автоматически, сделайте его структурой, а не классом. При передаче без клавиатуры «ref» среда выполнения теперь автоматически делает копию. Это делает для каждого члена копию. Он мелкий, как и конструктор копирования C ++ по умолчанию. Но без проблем с наложением указателей сборщик мусора решает эту проблему.
Но с проблемой мелкого копирования. На что большинство программистов C # берутся: «Я пробовал это раньше, не получилось. Давайте не будем делать это снова». Хороший совет, вы не должны делать это и в коде C ++. Это дорого и подвержено ошибкам, и вы лучше знаете, что делаете. Может быть, это слишком упрощает проблему. К сожалению.