Передача копией или ссылкой? - PullRequest
4 голосов
/ 24 августа 2010

Я немного новичок в C #, и мне было просто интересно, есть ли список классов (обычно используемых), которые по умолчанию передаются как копии. Как я могу их идентифицировать?

Я знаю, что основные базовые типы объектов - int, uint, float, strings, ... - передаются копией.

Ответы [ 4 ]

16 голосов
/ 24 августа 2010

В C # / .Net объекты могут быть классифицированы как значения или ссылочные типы [1].Типы значений - это любые типы, производные от System.ValueType и определенные в C # с объявлением типа struct.Они передаются копией / значением.

Ссылочные типы - это типы, которые не являются производными от System.ValueType и определены в C # с ключевым словом class.Идентификаторы экземпляров ссылочных типов называются ссылками (аналогично указателям).По умолчанию они также передаются по значению, но передается только ссылка, а не весь объект.

В вашем вопросе также упоминалось, что string экземпляры передаются копией.String в .Net является ссылочным типом (происходит непосредственно от System.Object) и, следовательно, не передается полной копией.

[1] Указатели могут заслужить здесь свой класс, но я игнорирую их для этого обсуждения.

11 голосов
/ 24 августа 2010

Все типы по умолчанию передаются по значению.Разница между типами значений (struct) и ссылочными типами (class) заключается в том, что для типов значений копия значения передается вметод, тогда как для ссылочных типов передается только ссылка.

См. MSDN для получения более подробной информации.

Кроме того, не путайте понятие значений / ссылочных типови понятие передачи параметров по значению или по ссылке.См. эту статью Джона Скита для деталей

3 голосов
/ 24 августа 2010

В общем

  • типы значений , которые включают в себя собственные типы (int, float, ...), а также struct s передаются «копией» (как вы это выразили) ), тогда как в

  • типы ссылок , включая class es, вместо полного объекта копируется только ссылка.

Обратите внимание, что строка не передается "копией"! Это ссылочный тип, но поскольку он неизменен, ведет себя подобно типу значения .

Обратите внимание, что ключевое слово ref может быть полезно в обоих случаях: в случае типов значений это означает, что значение копируется обратно. В случае ссылочных типов это означает, что ссылка может быть изменена (т. Е. Вы можете назначить переменную новому объекту, а не просто изменять свойства объекта.)

2 голосов
/ 24 августа 2010

Обратите внимание, что объекты структуры могут включать ссылочные типы:

struct Currency
{
    int Amount {get;set;} // is referenced by value (copy)
    string Code {get;set;} // is referenced by reference
}

Когда вы используете эту структуру, как это:

var obj1 = new Currency{Amount = 1, Code = "USD"};
var obj2 = obj1;

Тогда

object.ReferenceEquals(obj1.Code, obj2.Code); // false - string is reference type, but used inside value type

Есливы объявили Currency как класс, тогда ссылки на Code были одинаковыми.

...