Em sua essência tanto ref
e out
fornecer um mecanismo para passar o endereço de uma variável a um método para que ele possa ser atualizado - atribuindo ao ref
ou out
parâmetro atualiza a variável no contexto do chamador. Onde eles diferem está nas garantias: out
garante que a variável será atualizada, ref
não.
Do outro lado da chamada, existem diferenças semelhantes. out
Não é garantido que um parâmetro para nosso método contenha algo útil na chegada e deve ser definido como um valor em algum momento, enquanto um ref
parâmetro pode ser assumido como tendo um valor e não precisamos fazer nada específico com ele.
Essa diferença tem impactos na análise, geração e otimização de código que, embora não sejam muito aparentes para nós na maioria das vezes, podem ter alguns efeitos na maneira como nossos programas acabam operando. O gerador de código pode adiar a alocação da variável até imediatamente antes da chamada, o otimizador pode decidir que pode reordenar algumas operações com mais eficácia com base no contrato, etc.
Em termos de uso: como regra geral, uso out
para situações em que não me importo com o conteúdo da variável quando ela chega como parâmetro e ref
quando eu faço.