Depois que o C # 5 introduziu o modelo async
e await
para a programação assíncrona, a comunidade C # chegou a uma convenção de nomenclatura para adicionar um sufixo "Async" aos métodos que retornavam um tipo aguardável, como este:
interface Foo
{
Task BarAsync();
}
Muitos analisadores de código estático (baseados em Roslyn e não em Roslyn) foram escritos para depender dessa convenção de nomenclatura ao detectar o cheiro do código em torno da programação assíncrona.
Agora que o C # 8 introduziu o conceito de enumeráveis assíncronos, que não são aguardáveis, mas podem ser usados em conjunto com await foreach
, parece haver duas opções para retornar os métodos de nomeação IAsyncEnumerable
:
interface Foo
{
// No "Async" suffix, indicating that the return value is not awaitable.
IAsyncEnumerable<T> Bar<T>();
}
ou
interface Foo
{
// With "Async" suffix, indicating that the overall logic is asynchronous.
IAsyncEnumerable<T> BarAsync<T>();
}
Houve uma diretriz definitiva da convenção de nomenclatura (da equipe de linguagem C #, da .NET Foundation ou de outras autoridades) em relação às opções acima, como a convenção de nomenclatura C # 5 foi padronizada de maneira inequívoca e não deixada ao critério de opinião dos programadores?
async
e usoawait
dentro), e amostras MSDN mostra o mesmoAsync
sufixo para métodos que retornamIAsyncEnumerable
, por exemplo, ChannelReader.ReadAllAsync . Em outros casos, por exemplo, no EF Core,AsAsyncEnumerable()
é usado o que já está claroRespostas:
Não há orientação melhor do que o que as equipes do .NET já fazem:
IAsyncEnumerable<T>
IAsyncEnumerable
chamando AsAsyncEnumerable ()IAsyncEnumerable
sSystem.Linq.Async
mantêm seus nomes. Não háSelectAsync
ouSelectAsAsyncEnumerable
apenasSelect
.Em todos os casos, fica claro qual é o resultado do método. Em todos os casos, é necessário aguardar os resultados do método
await foreach
antes de poderem ser utilizados.Portanto, a diretriz real permanece a mesma - verifique se o nome deixa o comportamento claro :
AsAsyncEnumerable()
ouToAsyncEnumerable()
, não há necessidade de adicionar nenhum sufixo.Async
sufixo para que os desenvolvedores saibam que precisamawait foreach
do resultado.Os analisadores e geradores de código não se importam com os nomes dos métodos, eles detectam odores ao inspecionar o próprio código. Um analisador de código irá dizer-lhe que você se esqueceu de aguardar uma tarefa ou
await foreach
umIAsyncEnumerable
não importa como você chamar os métodos e as variáveis. Um gerador pode simplesmente usar a reflexão para verificarIAsyncEnumerable
e emitirawait foreach
São os analisadores de estilo que verificam os nomes. O trabalho deles é garantir que o código use um estilo consistente para que os desenvolvedores possam entender o código. O analisador de estilos informará que um método não segue o estilo escolhido. Esse estilo pode ser o guia de estilo da equipe ou geralmente aceito.
E, claro, todo mundo sabe que o prefixo comum para os campos de instância privada é
_
:)fonte
ChannelReader.ReadAllAsync
exemplo. Como isso vem diretamente da equipe do .NET, é difícil dar errado seguindo o exemplo.Como não é um método assíncrono, o nome não deve terminar em 'Assíncrono'. Esse sufixo do método é uma convenção para tornar óbvio que o método deve ser aguardado ou o resultado tratado como uma tarefa.
Eu acho que um nome normal de retorno de coleção é apropriado. GetFoos () ou similar.
fonte
Async
sufixo. O sufixo é usado no próprio .NET Core: ChannelReader.ReadAllAsync retorna um IAsyncEnumerable. UmIAsyncEnumerable
deve ser usado comawait foreach
, portanto o sufixo faz sentido.O sufixo assíncrono e até a palavra
async
- chave são apenas clichês, não têm sentido além de alguns argumentos de compatibilidade com versões anteriores. O C # possui todas as informações para distinguir essas funções, assim como se distingueyield
nos métodos que retornamIEnumerable
, como você sabe que não precisa adicionar nada parecidoenumerable
ou alguma outra palavra-chave a esses métodos.Você precisa adicionar o sufixo Async apenas porque o C # se queixará de sobrecargas, portanto, essencialmente, esses dois são idênticos e fazem a mesma coisa com todas as regras do polimorfismo (se não levarmos em consideração o fator humano de comportamento intencionalmente corrompido):
Mas você não pode escrever assim, porque o compilador irá reclamar. Mas ei! Engolirá essa monstruosidade:
e até isso:
Então é isso. Você adiciona o Async apenas para parar o compilador para reclamar. Não para esclarecer as coisas. Não para torná-los melhores. Se não houver reclamação - não há razão para adicioná-lo, então, no seu caso, evitarei isso, a menos que se torne
Task<IAsyncEnumerable>
.PS: Apenas para uma melhor compreensão da imagem inteira aqui - se em algum momento no futuro alguém adicionar extensões de método de computador quântico C # (fantazy, hein) que operam em paradigmas diferentes, provavelmente precisaremos de outro sufixo como Quant ou algo assim, porque C # reclamará o contrário. Será exatamente o mesmo método, mas funcionará de outra maneira. Assim como o polimorfismo. Assim como as interfaces fazem.
fonte