Здесь есть два понятия.
- Типы ссылок и типы значений
- Передача по значению против передачи по ссылке
Давайте сначала займемся вторым.
Передача чего-либо по значению означает, что вы предоставляете методу его собственную копию этого значения, и вы можете свободно изменять это значение по своему усмотрению, без каких-либо изменений, попадающих обратно в код, вызвавший метод.
Например, это:
Int32 x = 10;
SomeMethod(x); // pass by value
Нет никакого способа, которым x будет чем-то иным, чем 10, после того, как вызов вернется в этом случае, поскольку независимо от того, что SomeMethod сделал со своей копией значения, он сделал только со своим собственным значением.
Однако передача по ссылке означает, что мы на самом деле не присваиваем методу свое собственное значение, с которым мы можем играть, скорее мы даем ему место в памяти, где находится наше собственное значение, и, следовательно, все, что метод делает со значением, будет отражаться в нашем коде, потому что в действительности в игре есть только одно значение.
Итак, это:
Int32 x = 10;
SomeMethod(ref x); // pass by reference
В этом случае x может содержать другое значение после возврата SomeMethod, чем до вызова.
То есть, передача по значению вместо передачи по ссылке.
А теперь смутить воду. Есть еще одна концепция, ссылочные типы и типы значений, которые многих путают. Ваш вопрос намекает на то, что вы также запутались в этом вопросе, мои извинения, если вы нет.
Ссылочный тип на самом деле состоит из двух частей. Это ссылка, и это то, на что ссылается ссылка. Подумайте о доме, адрес которого вы знаете. Когда вы пишете адрес на листе бумаги, на самом деле весь дом не помещается на эту бумагу, скорее, у вас есть «ссылка» на этот конкретный дом на листе бумаги.
Ссылочный тип в .NET - это то же самое. Где-то в памяти есть объект, представляющий собой набор значений, сгруппированных вместе. Адрес этого объекта вы храните в переменной. Эта переменная объявляется как тип, который является ссылочным типом, который разрешает эту сделку из двух частей.
Хорошая вещь о ссылочных типах состоит в том, что у вас может быть много ссылок на один и тот же фактический объект, поэтому даже если вы скопируете ссылку вокруг, у вас останется только один объект в памяти.
Редактировать : В отношении вопроса массив является ссылочным типом. Это означает, что ваша переменная содержит только адрес фактического массива, и этот объект массива находится где-то еще в памяти.
Однако тип значения - это одно, все значение является частью «типа значения», и когда вы его копируете, вы делаете отдельные копии
Вот пример типов значений:
struct SomeType
{
public Int32 Value;
}
SomeType x = new SomeType;
x.Value = 10;
SomeType y = x; // value type, so y is now a copy of x
y.Value = 20; // x.Value is still 10
Однако для ссылочного типа вы не делаете копию объекта , на который он ссылается, только ссылка на него. Думайте об этом как о копировании адреса этого дома на второй лист бумаги. У вас все еще есть только один дом.
Итак, просто изменив тип SomeType на тип ссылки (изменив struct
на class
):
class SomeType
{
public Int32 Value;
}
SomeType x = new SomeType;
x.Value = 10;
SomeType y = x; // reference type, so y now refers to the same object x refers to
y.Value = 20; // now x.Value is also 20, since x and y refer to the same object
А теперь напоследок; передача ссылочного типа по значению.
Возьми этот метод:
public void Test(SomeType t)
{
t.Value = 25;
}
Учитывая нашу классовую версию SomeType выше, у нас есть метод, который принимает параметр ссылочного типа, но принимает его как передаваемый по значению.
Это означает, что Test не может изменить t
, чтобы ссылаться на другой объект в целом, и сделать это изменение обратно в вызывающий код. Думайте об этом как о том, чтобы позвонить другу и дать ему адрес, который у вас есть на вашем листе бумаги. Независимо от того, что твой друг делает с этим домом, адрес, который у тебя есть на бумаге, не изменится.
Но этот метод может свободно изменять содержимое объекта , являющегося , относящимся к . В этом сценарии дом / друг ваш друг может свободно посещать этот дом и переставлять мебель. Поскольку в игре только один дом, если вы перейдете в этот дом после того, как он перестроит его, вы увидите его изменения.
Если вы измените метод для передачи ссылочного типа по ссылке, этот метод не только свободен для переупорядочения содержимого объекта, на который ссылаются, но и метод также может заменить объект совершенно новым объектом, и иметь это изменение отражать обратно в вызывающий код. По сути, ваш друг может сказать вам: «С этого момента, используйте этот новый адрес, который я прочитаю вам, вместо старого, и вообще забудьте старый».