Vejo o seguinte padrão de código em todo o lugar na base de código da minha empresa (aplicativo .NET 3.5):
bool Foo(int barID, out Baz bazObject) {
try {
// do stuff
bazObject = someResponseObject;
return true;
}
catch (Exception ex) {
// log error
return false;
}
}
// calling code
BazObject baz = new BazObject();
fooObject.Foo(barID, out baz);
if (baz != null) {
// do stuff with baz
}
Estou tentando Foo
entender por que você faria isso, em vez de o método simplesmente pegar o ID e retornar um Baz
objeto, em vez de retornar um valor que não é usado e o objeto real ser um parâmetro ref ou output.
Há algum benefício oculto desse estilo de codificação que estou perdendo?
c#
code-quality
coding-style
Wayne Molina
fonte
fonte
baz
sernull
e obool
ser retornado nãofalse
são equivalentes. nunca é , portanto, a menos que seja atualizado antes do lançamento , quando retornado nunca será . Ele iria ajudar tremendamente se a especificação para estavam disponíveis. De fato, esse talvez seja o problema mais sério exibido por esse código.new BazObject()
null
bazObject
Exception
Foo
false
baz
null
Foo
Respostas:
Você costuma usar esse padrão para escrever código como este:
é usado no CLR for TryGetValue na classe de dicionário, por exemplo. Evita redundância, mas os parâmetros out e ref sempre pareciam um pouco confusos para mim
fonte
Este é um código antigo de estilo C, antes de haver exceções. O valor de retorno indicava se o método foi bem-sucedido ou não e, se fosse, o parâmetro seria preenchido com o resultado.
No .net, temos exceções para esse fim. Não deve haver razão para seguir esse padrão.
[edit] Obviamente, há implicações de desempenho no tratamento de exceções. Talvez isso tenha algo a ver com isso. No entanto, nesse trecho de código já existe uma exceção. Seria mais limpo deixá-lo subir a pilha até ficar preso em um local mais apropriado.
fonte
if (baz.Select())
mas, na maioria das vezes, o valor de retorno é jogado fora e o valor é verificado em relação a propriedades nulas ou alguma.Dado o trecho de código, parece completamente inútil. Para mim, o padrão de código inicial sugere que nulo para BazObject seria um caso aceitável e o retorno bool é uma medida de determinar um caso de falha com segurança. Se o seguinte código fosse:
Isso faria mais sentido para mim fazer dessa maneira. Talvez este seja um método que alguém antes de você estava usando para garantir que o baz estava sendo passado por referência sem entender como os parâmetros do objeto realmente funcionam em C #.
fonte
Às vezes, esse padrão é útil quando você, o responsável pela chamada, não deve se importar se o tipo retornado é um tipo de referência ou valor. Se você estiver chamando esse método para recuperar um tipo de valor, esse tipo de valor precisará de um valor inválido estabelecido (por exemplo, double.NaN) ou você precisará de alguma outra maneira de determinar o sucesso.
fonte
A idéia é retornar um valor que indique se o processo foi bem-sucedido, permitindo códigos como este:
Se o objeto não puder ser nulo (o que parece correto no seu exemplo), é melhor fazer o seguinte:
Se o objeto puder ser nulo, as exceções são o caminho a seguir:
É um padrão comum usado em C, onde não há exceções. Permite que a função retorne uma condição de erro. Exceções são geralmente uma solução muito mais limpa.
fonte