Чтобы ответить на ваш вопрос, давайте сначала посмотрим на ValueTypes
ValueType содержит значение. То есть он, в свою очередь, не указывает на другую ячейку памяти, в которой хранится значение, а вместо этого его ячейка памяти является значением.
так
int i = 10;
int j = i;
Что здесь происходит, так это то, что копия значения i присваивается j. Они оба имеют одинаковое значение, но они находятся в разных местах памяти. Другими словами, каждый раз, когда вы присваиваете тип значения другому типу значения, создается копия.
Заключите контракт с ReferenceTypes.
объект o = 10;
объект p = o;
потому что o является ReferenceType o указывает на область памяти, которая содержит значение 10 (это действительно в штучной упаковке, но я буду держать это простым). В следующей строке p теперь указывает на ту же ячейку памяти. Другими словами, у ссылочных связей есть две вещи.
1. Адресный указатель
2. Фактическая ячейка памяти (на которую указывает адрес), в которой хранится фактическая «вещь».
Если вы делаете это далеко, то мы можем перейти к передаче по значению и по ссылке.
В C # параметры передаются по значению. Поэтому, если вы передаете valueType методу, который ожидает параметр valuetype, тогда
int i = 10;
SomeMethod(i);
Console.WriteLine(i);
static void SomeMethod(int value)
{
value = 20;
}
Когда выполняется вызов SomeMethod, в метод отправляется копия значения i. Если метод манипулирует параметром, он не влияет на исходную переменную i. Так что в окне консоли вы увидите 10;
заключить это с ссылочными типами;
class Program
{
static void Main(string[] args)
{
Customer c = new Customer() { Name = "Mike" };
SomeMethod(c);
Console.WriteLine(c.Name);
}
static void SomeMethod(Customer customer)
{
customer.Name = "John";
}
}
class Customer
{
public string Name { get; set; }
}
Поскольку c является ссылочным типом. И C # передает параметры по значению. копия «значения» ссылки передается. То есть значение адреса, на которое указывает c, передается. В методе, поскольку адрес один и тот же (это копия, но она указывает на то же место в памяти), метод может манипулировать состоянием объекта. Так что в окне консоли вы увидите «Джона», а не «Майка».
Однако, если метод пытается назначить другой экземпляр параметру (в данном случае это называется «клиент»). тогда все изменится.
class Program
{
static void Main(string[] args)
{
Customer c = new Customer() { Name = "Mike" };
SomeMethod(c);
Console.WriteLine(c.Name);
}
static void SomeMethod(Customer customer)
{
customer = new Customer();
customer.Name = "John";
}
}
class Customer
{
public string Name { get; set; }
}
Обратите внимание, что в этом методе мы создаем новый экземпляр Customer и присваиваем его параметру customer, а также присваиваем имя этому новому экземпляру значение «John». В окне консоли мы увидим «Майк», а не Джон.
Это потому, что копия исходной переменной (c) была сделана до ее передачи в метод. В то время как теперь в методе у нас есть другой адрес, а затем манипулируем этим новым адресом, чтобы исходный экземпляр не затрагивался. Имеет смысл?
Хорошо, если это имеет смысл. тогда что, если мы действительно хотим, чтобы SomeMethod мог делать то, что мы пытались сделать? Ну, тогда параметр не может быть передан по значению, но он должен быть передан по ссылке. Это означает, что переменная c и две части (значение адреса, на которое она указывает, и сам адрес) передаются. Итак, теперь вы передаете ссылочный тип по ссылке.
class Program
{
static void Main(string[] args)
{
Customer c = new Customer() { Name = "Mike" };
SomeMethod(ref c);
Console.WriteLine(c.Name);
}
static void SomeMethod(ref Customer customer)
{
customer = new Customer();
customer.Name = "John";
}
}
class Customer
{
public string Name { get; set; }
}