C # fornece a ref
ea out
palavra-chave para argumentos fazer para ser passado por referência. A semântica dos dois é muito semelhante. A única diferença está na inicialização da variável flaged:
ref
requer que a variável seja inicializada antes de passá-la para a função,out
não.out
requer que a variável seja inicializada dentro da função,ref
não.
Os casos de uso dessas duas palavras-chave também são quase os mesmos, e seu uso muito frequente é considerado um cheiro de código (embora existam casos de uso válidos, como os padrões TryParse
e TryGetValue
).
Por isso, alguém poderia explicar, por que existem duas ferramentas muito semelhantes em C # para casos de uso tão restritos?
Além disso, no MSDN , afirma-se que eles têm um comportamento de tempo de execução diferente:
Embora as palavras-chave ref e out causem um comportamento de tempo de execução diferente, elas não são consideradas parte da assinatura do método no tempo de compilação.
Qual a diferença entre o comportamento em tempo de execução?
Conclusão
Ambas as respostas parecem corretas, obrigado a ambos. Aceitei o jmoreno porque é mais explícito.
fonte
ref
em C ++; para ponteiros para o ponteiro de objeto (ou primitivo) em questão. ieInt32.TryParse(myStr, out myInt)
(C #) é "executado" da mesma maneira queint32_tryParse(myStr, &myInt)
(C) seria; a única diferença são algumas restrições impostas pelo compilador para evitar bugs. (Eu não vou postar isso como uma resposta porque eu posso estar errado sobre como isso funciona nos bastidores, mas é assim que eu imagino ele funciona [porque faz sentido])Respostas:
No momento em que essa pergunta foi feita, o artigo do MSDN estava sutilmente incorreto ( já foi corrigido ). Em vez de "causar comportamento diferente", deveria ser "requer comportamento diferente".
Em particular, o compilador impõe requisitos diferentes para as duas palavras-chave, mesmo que o mesmo mecanismo (IL) seja usado para habilitar o comportamento.
fonte
out
parâmetro ou não atribuir umref
parâmetro, mas a IL que ele emite é apenas uma referência de qualquer maneira. Isso está correto?out T
eref T
são prestados de forma idêntica em outros idiomas CLI como VB.Net ou C ++ / CLI.Aqui está um artigo interessante sobre o tópico que pode responder à sua pergunta:
http://www.dotnetperls.com/ref
ponto de interesse:
"A diferença entre ref e out não está no Common Language Runtime, mas está na própria linguagem C #."
atualizar:
o desenvolvedor sênior do meu trabalho corroborou a resposta de @ jmoreno, portanto, leia-a !.
fonte
string
tem a ver com tudo isso?Tempo de execução ? Absolutamente nenhum. Você não pode sobrecarregar um método com os mesmos parâmetros que diferem apenas pela palavra-chave ref ou out.
Tente compilar isso e você receberá um erro de compilação "O método com a mesma assinatura já está declarado":
Para responder a esta pergunta: "... por que existem duas ferramentas muito semelhantes em C # para casos de uso tão restritos?"
Do ponto de vista da legibilidade do código e da API, há uma enorme diferença. Como consumidor da API, sei que quando "out" é usado, a API não depende do parâmetro out. Como desenvolvedor de API, eu prefiro o "out" e uso o "ref" somente quando absolutamente (RARAMENTE!) Necessário. Veja esta referência para uma ótima discussão:
/programming/1516876/when-to-use-ref-vs-out
Informações de suporte: compilei o método a seguir e desmontei. Usei as palavras-chave ref e out (neste exemplo), mas o código do assembly não mudou, exceto por uma referência de endereço, como seria de esperar:
00000000 push ebp
00000001 mov ebp, esp
00000003 push edi
00000004 push esi
00000005 push ebx
00000006 subesp, 34h
00000009 xor eax, eax
0000000b mov dword ptr [ebp-10h], eax
0000000e mov dword ptr [ebp-1Ch], eax
00000011 mov dword ptr [ebp-3Ch], ecx
00000014 mov dword ptr [ebp-40h], edx
00000017 cmp dword ptr ds: [008B1710h], 0
0000001e je 00000025
00000020 chamada 6E6B601E
00000025 nop
param = 0;
00000026 mov eax, dword ptr [ebp-40h]
00000029 xor edx, edx
0000002b mov dword ptr [eax], edx
}
0000002d de
0000002e lea esp, [ebp-0Ch]
00000031 pop ebx
00000032 pop esi
00000033 pop edi 00000033 pop edi
00000034 pop ebp
00000035 ret
Estou lendo a montagem corretamente?
fonte