Я собираюсь попробовать свои силы в объяснении:
Я думаю, мы понимаем, как типы значений работают правильно? Типы значений (int, long, struct и т. Д.). Когда вы отправляете их в функцию без команды ref, она копирует данные . Все, что вы делаете с этими данными в функции, влияет только на копию, а не на оригинал. Команда ref отправляет ФАКТИЧЕСКИЕ данные, и любые изменения будут влиять на данные вне функции.
Хорошо, к запутанной части, ссылочные типы:
Давайте создадим ссылочный тип:
List<string> someobject = new List<string>()
Когда вы создаете новый объект , создаются две части:
- Блок памяти, который содержит данные для некоторого объекта .
- Ссылка (указатель) на этот блок данных.
Теперь, когда вы отправляете некоторый объект в метод без ссылки, он КОПИРУЕТ указатель ссылки , а НЕ данные. Итак, теперь у вас есть это:
(outside method) reference1 => someobject
(inside method) reference2 => someobject
Две ссылки, указывающие на один и тот же объект. Если вы изменяете свойство в каком-либо объекте, используя reference2, это повлияет на те же данные, на которые указывает reference1.
(inside method) reference2.Add("SomeString");
(outside method) reference1[0] == "SomeString" //this is true
Если вы обнулите reference2 или укажете на новые данные, это не повлияет на reference1 или на reference1.
(inside method) reference2 = new List<string>();
(outside method) reference1 != null; reference1[0] == "SomeString" //this is true
The references are now pointing like this:
reference2 => new List<string>()
reference1 => someobject
Теперь, что происходит, когда вы отправляете некий объект по ссылке на метод? Фактическая ссылка на SomeObject отправляется к методу. Теперь у вас есть только одна ссылка на данные:
(outside method) reference1 => someobject;
(inside method) reference1 => someobject;
Но что это значит? Он действует точно так же, как отправка объекта не по ссылке, за исключением двух основных моментов:
1) Когда вы обнуляете ссылку внутри метода, она обнуляет ссылку вне метода.
(inside method) reference1 = null;
(outside method) reference1 == null; //true
2) Теперь вы можете указать ссылку на совершенно другое местоположение данных, и ссылка вне функции теперь будет указывать на новое местоположение данных.
(inside method) reference1 = new List<string>();
(outside method) reference1.Count == 0; //this is true
MyClass
это будетclass
тип, то есть ссылочный тип. В этом случае передаваемый вами объект может быть измененmyFunction
даже без ключевого словаref
/out
.myFunction
получит новую ссылку, которая указывает на тот же объект, и он может изменять тот же объект столько, сколько он хочет. Различиеref
, которое могло бы иметь ключевое слово, заключалось бы в том, что онmyFunction
получал одну и ту же ссылку на один и тот же объект. Это было бы важно, только еслиmyFunction
бы изменить ссылку, чтобы указать на другой объект.