Vou tentar uma explicação:
Acho que entendemos como os tipos de valor funcionam, certo? Os tipos de valor são (int, long, struct etc.). Quando você os envia para uma função sem um comando ref, copia os dados . Tudo o que você faz com esses dados na função afeta apenas a cópia, não o original. O comando ref envia os dados ATUAIS e quaisquer alterações afetarão os dados fora da função.
Aprovação para a parte confusa, tipos de referência:
Vamos criar um tipo de referência:
List<string> someobject = new List<string>()
Quando você cria um novo objeto , duas partes são criadas:
- O bloco de memória que contém dados para algum objeto .
- Uma referência (ponteiro) para esse bloco de dados.
Agora, quando você envia um objeto para um método sem ref, ele copia o ponteiro de referência , NÃO os dados. Então agora você tem isso:
(outside method) reference1 => someobject
(inside method) reference2 => someobject
Duas referências apontando para o mesmo objeto. Se você modificar uma propriedade em algum objeto usando a referência2, ela afetará os mesmos dados apontados pela referência1.
(inside method) reference2.Add("SomeString");
(outside method) reference1[0] == "SomeString" //this is true
Se você anular a referência2 ou apontá-la para novos dados, ela não afetará a referência1 nem a referência1 dos dados.
(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
Agora, o que acontece quando você envia algum objeto por ref para um método? A referência real a algum objeto é enviada ao método. Então agora você tem apenas uma referência aos dados:
(outside method) reference1 => someobject;
(inside method) reference1 => someobject;
Mas o que isso significa? Ele age exatamente da mesma forma que o envio de algum objeto, não por ref, exceto por duas coisas principais:
1) Quando você anula a referência dentro do método, ela anula a referência fora do método.
(inside method) reference1 = null;
(outside method) reference1 == null; //true
2) Agora você pode apontar a referência para um local de dados completamente diferente e a referência fora da função agora apontará para o novo local de dados.
(inside method) reference1 = new List<string>();
(outside method) reference1.Count == 0; //this is true
MyClassseria umclasstipo, ou seja, um tipo de referência. Nesse caso, o objeto que você passa pode ser modificado pelomyFunctionmesmo semref/outpalavra-chave.myFunctionreceberá uma nova referência que aponta para o mesmo objeto e pode modificar o mesmo objeto o quanto desejar. A diferença que arefpalavra - chave faria seriamyFunctionreceber a mesma referência ao mesmo objeto. Isso seria importante apenas semyFunctionmudássemos a referência para apontar para outro objeto.