Después de que C # 5 presentó el modelo async
y await
para la programación asincrónica, la comunidad C # llegó a una convención de nomenclatura para agregar un sufijo "Async" a los métodos que devuelven un tipo esperado, como este:
interface Foo
{
Task BarAsync();
}
Desde entonces, se ha escrito que muchos analizadores de código estático (tanto basados en Roslyn como no basados en Roslyn) dependen de esta convención de nomenclatura al detectar el olor del código en torno a la programación asincrónica.
Ahora que C # 8 ha introducido el concepto de enumerables asincrónicos, que no son esperados pero que pueden usarse en conjunto await foreach
, parece que hay dos opciones para devolver los métodos de nombres IAsyncEnumerable
:
interface Foo
{
// No "Async" suffix, indicating that the return value is not awaitable.
IAsyncEnumerable<T> Bar<T>();
}
o
interface Foo
{
// With "Async" suffix, indicating that the overall logic is asynchronous.
IAsyncEnumerable<T> BarAsync<T>();
}
¿Ha habido una directriz definitiva para la convención de nomenclatura (del equipo del lenguaje C #, la Fundación .NET u otras autoridades) con respecto a las opciones anteriores, como cómo la convención de nomenclatura C # 5 fue estandarizada sin ambigüedades y no se dejó al criterio de los programadores basado en la opinión?
async
y useawait
dentro), y el ejemplo msdn muestra lo mismoAsync
sufijo para los métodos que regresanIAsyncEnumerable
, por ejemplo, ChannelReader.ReadAllAsync . En otros casos, por ejemplo, en EF Core,AsAsyncEnumerable()
se usa lo que ya está claroRespuestas:
No hay mejor directriz que lo que los equipos .NET ya hacen:
IAsyncEnumerable<T>
IAsyncEnumerable
llamando a AsAsyncEnumerable ()IAsyncEnumerable
sSystem.Linq.Async
conservan sus nombres. No haySelectAsync
oSelectAsAsyncEnumerable
, simplementeSelect
.En todos los casos, está claro cuál es el resultado del método. En todos los casos, los resultados del método deben esperarse
await foreach
antes de que puedan usarse.Por lo tanto, la pauta real sigue siendo la misma: asegúrese de que el nombre aclare el comportamiento :
AsAsyncEnumerable()
oToAsyncEnumerable()
, no es necesario agregar ningún sufijo.Async
sufijo para que los desarrolladores sepan que necesitanawait foreach
el resultado.Los analizadores y generadores de código no se preocupan realmente por los nombres de los métodos, detectan olores al inspeccionar el código en sí. Un analizador de código le dirá que ha olvidado a la espera de una tarea o
await foreach
unIAsyncEnumerable
no importa cómo se llama a los métodos y las variables. Un generador puede simplemente usar la reflexión para verificarIAsyncEnumerable
y emitirawait foreach
Son los analizadores de estilo los que verifican los nombres. Su trabajo es garantizar que el código use un estilo consistente para que los desarrolladores puedan entender el código. El analizador de estilo le dirá que un método no sigue el estilo que eligió. Ese estilo puede ser el del equipo o una guía de estilo comúnmente aceptada.
Y, por supuesto, todos saben que el prefijo común para los campos de instancia privada es
_
:)fuente
ChannelReader.ReadAllAsync
ejemplo. Dado que esto proviene directamente del equipo .NET, es difícil equivocarse siguiendo el ejemplo.No es un método asíncrono, por lo que el nombre no debe terminar en 'Asíncrono'. Ese sufijo de método es una convención para hacer obvio que el método debe esperarse o que el resultado debe manejarse como una Tarea.
Creo que un nombre normal de devolución de colección es apropiado. GetFoos (), o similar.
fuente
Async
sufijo. El sufijo se usa en .NET Core: ChannelReader.ReadAllAsync devuelve un IAsyncEnumerable. SeIAsyncEnumerable
debe usar Anawait foreach
, por lo que el sufijo tiene sentido.El sufijo asíncrono e incluso la palabra clave
async
es simplemente repetitivo, no tiene sentido aparte de algunos argumentos de compatibilidad con versiones anteriores. C # tiene toda la información para distinguir esas funciones al igual que se distingueyield
en los métodos que se devuelvenIEnumerable
, ya que sabe que no necesita agregar nada parecidoenumerable
o alguna otra palabra clave en dichos métodos.Debe agregar el sufijo Async solo porque C # se quejará de sobrecargas, por lo que esencialmente esos dos son idénticos y hacen lo mismo según todas las reglas del polimorfismo (si no tomamos en cuenta el factor humano de comportamiento de corrupción intencional):
Pero no puedes escribirlo así porque el compilador se quejará. ¡Pero hey! Se tragará esta monstruosidad:
e incluso esto:
Así que esto es todo. Agrega Async solo para detener el compilador para quejarse. No para aclarar las cosas. No para hacerlos mejores. Si no hay ninguna queja, no hay razón para agregarla, así que en su caso evitaré esto, a menos que se convierta
Task<IAsyncEnumerable>
.PD: Solo para comprender mejor la imagen completa aquí: si en algún momento en el futuro alguien agrega extensiones de método de computadora cuántica C # (fantazy, huh) que operarán en un paradigma diferente, probablemente necesitemos otro sufijo como Quant o algo así, porque C # se quejará de lo contrario. Será exactamente el mismo método, pero funcionará de otra manera. Al igual que el polimorfismo. Al igual que las interfaces.
fuente