Por que o C # tem tanto out quanto ref?

18

C # tem as palavras out- refchave Por que esses dois são necessários? Isenção de responsabilidade: não tenho conhecimento profundo de c #.

Neo
fonte
3
Não há uma duplicata entre sites no estouro de pilha?
Peter Mortensen
2
Você está pedindo a diferença entre refe out? Ou você está perguntando qual é o uso de argumentos por referência ref/ outem comparação com argumentos por valor (sem modificador para o parâmetro)? Ou ambos?
Jeppe Stig Nielsen
1
Eu sinto que esta questão é semelhante, mas não completamente um dup - pelo menos se for levado do ponto de vista design de linguagem
jmoreno

Respostas:

32

Em termos de implementação, eles são essencialmente a mesma coisa, mas outcomunica algo que refnão acontece: você não se importa com a entrada. Isso significa certas coisas para você e ferramentas. Por exemplo, você pode passar uma variável não inicializada para um outparâmetro e isso não é um problema, onde seria caso contrário, e dentro da função é necessário atribuir um valor ao outparâmetro antes que ele retorne, enquanto não há necessidade de fazer nada em tudo com um refvalor.

Mason Wheeler
fonte
10
Ref vs out é muito mais importante para o compilador do que para um programador. O compilador é obrigado a garantir que você não leia uma variável antes de lhe ser atribuído um valor, e outfornece uma maneira de fazê-lo, que melhor corresponde à maneira como você deseja lidar com as variáveis ​​em primeiro lugar.
Cort Ammon - Repor Monica
Você poderia, por favor, elaborar sobre: ​​'out' comunica algo que 'ref' não.
Neo
4
@Neo: Basicamente, o que eu disse na resposta: comunica que você não se preocupa em usar isso para entrada e, portanto, é seguro passar um valor não inicializado para um outparâmetro, porque a função que o recebe não vai ler dele .
Mason Wheeler
@MasonWheeler Isso é permitido (e / ou aplicado no final do recebimento) pelo verificador? Out é apenas um atributo, internamente.
Random832
@ Random832: Como Robert postou em sua resposta, ter um olhar para Eric Lippert (ex-compilador C # cara) discutir isso em stackoverflow.com/q/2876315
Mason Wheeler
7

Para entender essas duas palavras-chave, você precisará entender o que significa passar um valor por referência . Essencialmente, isso significa que, se você modificar a variável de parâmetro que você transmite dentro do método ou função, essa variável reterá seu valor modificado quando sua função sair. Declarar um parâmetro como refou outrealiza isso, enquanto uma variável de parâmetro comum manteria seu valor original, mesmo se você o modificasse na função.

As únicas diferenças entre refe outé que outnão exigem que você inicialize a variável antes de passá-la para a função, mas refsim; enquanto out faz necessário que você atribuir algo para a variável dentro da função, mas refnão o faz.

Robert Harvey
fonte
Não existe uma diferença relacionada à variação?
monocell
Veja a resposta de Eric Lippert em stackoverflow.com/q/2876315
Robert Harvey
2

Você perguntou.

C # tem out e ref, por que esses dois são necessários. Eu não tenho conhecimento profundo de c #. Por que parâmetros out e ref são necessários?

E a resposta é que eles não são NECESSÁRIOS, java, por exemplo, também não tem e o VB apenas possui ref (e somente o requer na declaração do método).

Você pode escrever facilmente um programa inteiro sem usar nenhum dos dois.

Eles existem porque são ocasionalmente úteis. É por isso que existem dois deles e não apenas um - porque é útil fazer a distinção entre 'aqui está alguma coisa, modifique-a se você quiser' e 'dê a essa coisa um novo valor'.

Outros idiomas têm prioridades diferentes e, portanto, podem ou não incluir essas ou equivalentes. Eles podem até discordar sobre se um deles é útil e, portanto, podem decidir ativamente NÃO implementar um ou outro.

jmoreno
fonte
1

Em sua essência tanto refe outfornecer um mecanismo para passar o endereço de uma variável a um método para que ele possa ser atualizado - atribuindo ao refou outparâmetro atualiza a variável no contexto do chamador. Onde eles diferem está nas garantias: outgarante que a variável será atualizada, refnão.

Do outro lado da chamada, existem diferenças semelhantes. outNã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 refparâ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 outpara situações em que não me importo com o conteúdo da variável quando ela chega como parâmetro e refquando eu faço.

Corey
fonte