Por que as diretrizes do .NET Framework recomendamos que você não use ref / out argumentos?

StackOverflow https://stackoverflow.com/questions/214688

  •  03-07-2019
  •  | 
  •  

Pergunta

Aparentemente, eles são "confusas". É que seriamente o motivo? Você pode pensar em quaisquer outros?

Foi útil?

Solução

Você já viu quantos desenvolvedores realmente não entendo ref / out?

Eu usá-los onde eles são realmente necessários, mas não o contrário. Eles são geralmente só é útil se você quiser retornar efetivamente dois ou mais valores - no caso vale a pena que, pelo menos, pensamento sobre se há uma maneira de fazer o método faz uma coisa em seu lugar. Às vezes usando ref / out é a abordagem mais adequada -. Os vários métodos TryParse etc

Outras dicas

Na minha opinião, eles são considerados um cheiro de código, porque, em geral, não é uma opção muito melhor:. Retornando um objeto

Se você observar, na biblioteca .NET eles são usados ??apenas em alguns casos especiais, ou seja, TryParse cenários -como onde:

  • retornar uma classe significaria boxe um tipo de valor
  • o contrato do método requer que ele seja rápido, e assim boxing / unboxing não é uma opção viável.

ref / out significa automaticamente mutabilidade, e programação funcional com valores imutáveis ??é toda a raiva estes dias. Tente inserir uma chamada para Dictionary.TryGetValue em uma consulta LINQ. A API requer declarar variáveis ??e arruína qualquer 'fluência' na API.

Isso não quer dizer que esta é "a razão", mas é um exemplo de "uma razão".

(Ver também

http://lorgonblog.spaces.live.com/blog /cns!701679AD17B6D310!181.entry

para comentário sobre como linguagens funcionais lidar com essas APIs.)

Confundindo é provavelmente a melhor razão. confundir meios de manutenção diminuída e aumento da probabilidade de introduzir erros subtis. Eu vê-los em uma vista semelhante à demonstração dos fluxos de controle "goto". Enquanto não é inerentemente mau por sua própria vontade, ele tem levado a muitos muitos impossível de ler / entender programas ao longo das décadas.

Fique longe de qualquer coisa que pode tornar seu código mais confuso, então ele precisa ser.

Dito isso, essas palavras-chave existem provavelmente porque a necessidade desenvolvedores quadro serra para essas coisas. Use-os se não houver nenhuma solução adequada, mas evitá-los quando puder.

ref / out também não funcionam com os delegados "Func", de modo que essas APIs de estilo são menos combináveis ??/ reutilizável com algumas outras APIs que usar delegados.

Apenas um pensamento, acho ref / out para ser útil quando os argumentos capturar o estado de execução no método de destino, em vez de capturar dados retornados. Considere um cenário em que você deseja obter uma mensagem de erro a partir de um serviço que objeto retorna ao cliente.

Customer GetCustomerById(int id, out string errorMessage);

Se este método falhar, você provavelmente voltar Customer objeto nulo ou lançar uma exceção. No entanto, se eu quero saber a causa do erro (de validação? Banco de dados?), Eu usaria o argumento. argumento errorMessage aqui não tem nada a ver com os dados, simplesmente usado para capturar o que está errado com a execução do método.

Pessoalmente, se eu tenho um método que é esperado para retornar dois ou mais essenciais dados / valores, gostaria de repensar a concepção do meu código.

A razão me foi dito é o 1.0 GC teve problemas quando foi utilizado ref / out. A GC em 2.0 (e provavelmente não 1.1 também) não tem esses problemas, então eu seria normalmente assumir que é um legado agora não-útil.

@TraumaPony Seria bom se você nos dá uma fonte (URL ou algo) para este guidlines .NET framework.

Você deve estar retornando objetos é provavelmente a razão mais provável que eles não sugiro usar ref ou para fora.

"ref" realmente precisa para ser usada apenas quando passar valores escalares, mas eu vejo as pessoas usá-lo muitas vezes para objetos que estão sendo passados ??por referência de qualquer maneira.

Não é o código de razão complexidade suficiente? Compare:

int myValue;
ReadFromSomewhere(ref myValue);

Para:

int myValue = ReadFromSomewhere();
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top