IAsyncEnumerable döndüren yöntemler için kesin bir adlandırma kuralı var mı?


10

C # 5 , eşzamansız programlama için asyncve awaitmodelini tanıttıktan sonra , C # topluluğu, aşağıdaki gibi beklenen bir tür döndüren yöntemlere bir "Eşzamansız" son ek eklemek için bir adlandırma kuralına geldi:

interface Foo
{
   Task BarAsync();
}

Birçok statik kod analizörü (hem Roslyn tabanlı hem de Roslyn tabanlı değil) o zamandan beri eşzamansız programlama etrafında kod kokusu algılandığında bu adlandırma kuralına bağlı olarak yazılmıştır.

Şimdi C # 8, kendileri beklenmeyen ancak birlikte kullanılabilen asenkron numaralandırılabilir kavramını tanıttığına göre, await foreachgeri dönen yöntemleri adlandırmak için iki seçenek var gibi görünüyor IAsyncEnumerable:

interface Foo
{
    // No "Async" suffix, indicating that the return value is not awaitable.
    IAsyncEnumerable<T> Bar<T>();
}

veya

interface Foo
{
    // With "Async" suffix, indicating that the overall logic is asynchronous.
    IAsyncEnumerable<T> BarAsync<T>();
}

Yukarıdaki seçeneklerle ilgili olarak, C # 5 adlandırma kuralının nasıl net bir şekilde standartlaştırıldığı ve programcıların fikir tabanlı kararına bırakılmadığı gibi, kesin bir adlandırma kuralları kılavuzu (C # dil ekibinden, .NET Vakfı'ndan veya diğer yetkililerden) var mı?


2
Seçenek 2 burada doğru geliyor, çünkü bu kodu eşzamansız olarak çalıştır (yöntemi işaretleyin asyncve awaitiçeride kullanın ) ve msdn örneği aynı gösteriyor
Pavel Anikhouski

1
Sorunun kapanmasına yanıt olarak, kesin bir adlandırma kuralının olup olmadığını sormak ve C # 5'teki kesin bir adlandırma kuralının statik kod analizindeki gelişmelere nasıl yol açtığına dair örnek vermek için soruyu düzenledim. Bu nedenle, C # 8'in bu kalıbı izlemesi, görüş tabanlı kodlama tercihlerinin ötesinde ölçülebilir kod kalitesi iyileştirmeleri ile sonuçlanacaktır.
hwaien

.NET Core Async, geri dönen yöntemler için sonek kullanır IAsyncEnumerable, örn. ChannelReader.ReadAllAsync . Diğer durumlarda, örneğin AsAsyncEnumerable()zaten açık olan EF Core'da kullanılır
Panagiotis Kanavos

Adlandırma yönergeleri, insanların kodu anlamasını kolaylaştırmak için mevcuttur. Kodun amacı net değilse, soneki ekleyin.
Panagiotis Kanavos

Yanıtlar:


1

NET ekipleri olandan daha iyi bir kılavuz var zaten yapın:

  • ChannelReader.ReadAllAsync birIAsyncEnumerable<T>
  • EF Core 3'te, sonuçlar AsAsyncEnumerable ()IAsyncEnumerable çağrılarak bir
  • System.Linq.Async'de ToAsyncEnumerable () , IEnumerables, Görevler ve Gözlemlenebilir ÖğeleriIAsyncEnumerable s
  • Tüm diğer operatörler System.Linq.Asyncisimlerini saklı tutarlar. Yok SelectAsyncya da SelectAsAsyncEnumerablesadece Select.

Her durumda, yöntemin sonucunun ne olduğu açıktır. Her durumda, await foreachkullanılmadan önce yöntemin sonuçlarının beklenmesi gerekir .

Böylece gerçek kılavuz aynı kalır - adın davranışı netleştirmesini sağlayın :

  • Ad zaten açık olduğunda, örneğin AsAsyncEnumerable()veya ile ToAsyncEnumerable(), herhangi bir sonek eklemenize gerek yoktur.
  • Diğer durumlarda, geliştiricilerin sonuca ihtiyaçları olduğunu bilmesi için Asyncsoneki ekleyin .await foreach

Kod analizörleri ve jeneratörleri yöntemlerin isimlerini gerçekten önemsemiyorlar, kodun kendisini inceleyerek kokuları tespit ediyorlar. Bir kod analizörü, bir görev veya beklemek üzere unuttum söyleyecektir await foreachbir IAsyncEnumerableolursa olsun yöntemleri ve değişkenleri çağrı nasıl. Bir jeneratör, kontrol etmek IAsyncEnumerableve yaymak için yansımayı kullanabilirawait foreach

İsimleri kontrol eden stil analizörleri. Görevleri, kodun tutarlı bir stil kullanmasını sağlamaktır, böylece geliştiriciler kodu anlayabilir. Stil analizörü, bir yöntemin seçtiğiniz stile uymadığını söyleyecektir. Bu tarz, ekibin veya yaygın olarak kabul edilen bir stil rehberi olabilir.

Ve tabii ki, herkes özel örnek alanları için ortak önek olduğunu biliyor _:)


ChannelReader.ReadAllAsyncÖrneği işaret ettiğiniz için teşekkür ederiz . Bu doğrudan .NET ekibinden geldiğinden, davayı takiben yanlış gitmek zor.
hwaien

Analizör paketleri genellikle bir stil çantası ve stil olmayan analizörler içerir. Örneğin, Microsoft.VisualStudio.Threading.Analyzers paketinde adlandırma kuralını (VSTHRD200) kontrol eden bir stil analizörü ve potansiyel olarak kilitlenmeye yol açabilecek tehlikeli durumları tespit eden bir stil analizörü vardır (VSTHRD111). VSTHRD111'den yararlanmak için pakete başvurmak için bir proje de VSTHRD200 ile sonuçlanacaktır.
hwaien

2

Bu bir zaman uyumsuz yöntem değildir, bu nedenle ad 'Zaman uyumsuz' ile bitmemelidir. Bu yöntem soneki, yöntemin beklenmesi veya sonucun bir Görev olarak ele alınması gerektiğini açıkça ortaya koyan bir kuraldır.

Normal bir koleksiyon döndüren adın uygun olduğunu düşünüyorum. GetFoos () veya benzeri.


Tüm bu argümanlar vardır için kullanarak Asynceki. Sonek .NET Core'un kendisinde kullanılır: ChannelReader.ReadAllAsync bir IAsyncEnumerable döndürür. An IAsyncEnumerableile birlikte kullanılmalıdır await foreach, bu nedenle sonek mantıklıdır.
Panagiotis Kanavos

1

Async soneki ve hatta anahtar kelime asyncsadece ortak özelliktir, geriye dönük uyumluluk argümanlarından başka anlamsızdır. C #, bu işlevleri , bu yöntemlere benzer bir şey veya başka bir anahtar kelime eklemeniz gerekmediğini bildiğiniz gibi, yielddöndürülen yöntemlerde olduğu gibi ayırt etmek için tüm bilgilere sahiptir .IEnumerableenumerable

Async sonekini sadece C # aşırı yüklerden şikayet edeceği için eklemeniz gerekir , bu yüzden aslında bu ikisi aynıdır ve tüm polimorfizm kuralları ile aynı şeyi yaparlar (eğer insan faktörünü kasıtlı olarak bozan davranışı hesaba katmazsak):

public interface IMyContract
{
    Task<int> Add(int a, int b);
    int Add(int a, int b);
}

Ama bunu böyle yazamazsınız çünkü compilator şikayet edecek. Ama hey! Bu bir canavarlığı yutacak:

public interface IMyContract : IEnumerable<int>, IEnumerable<long>
{
}

ve hatta bu:

public interface IMyContractAsync
{
    Task<int> Add(int a, int b);
}

public interface IMyContract : IMyContractAsync
{
    int Add(int a, int b);
}

İşte bu kadar. Derleyiciyi şikayet etmek için durdurmak için Async'i eklersiniz . Açıklığa kavuşturmamak için. Onları daha iyi yapmak için değil. Şikayet yoksa - eklemek için bir neden yok, bu yüzden olmadıkça, bundan kaçınacağım Task<IAsyncEnumerable>.

Not: Sadece burada tüm resmin daha iyi anlaşılması için - gelecekte birileri farklı paradigmada çalışacak C # kuantum-bilgisayar yöntemi uzantıları (fantazy, huh) eklerse, muhtemelen Quant veya başka bir şey gibi başka bir son eke ihtiyacımız olacaktır , çünkü C # aksi şikayet edecek. Aynı yöntem olacak, ancak başka bir şekilde çalışacak. Tıpkı polimorfizm gibi. Tıpkı arayüzlerin yaptığı gibi.


1
Üzgünüm, ama aynı fikirde olmadığımı hissediyorum, aynı şeyi yapmak gerçekten farklı bir yaklaşım değil - daha fazlası - farklı olarak adlandırılması ve farklı şekilde toplanması bekleniyor. Bu, zaman uyumsuz ve zaman uyumsuz arasındaki en büyük farktır. Async'i eklemenin netlik için olduğuna inanıyorum. Bence bu da Microsoft'un tavsiyesi.
madoxdev

Evet, katılıyorum ama katılmıyorum. Listede olduğu gibi "QuickSort", "RadixSort", "BubbleSort", "MixOfSorts" değil basit Sıralama işlevine sahipsiniz. Farklıdır, kapsam tarafından kullanılırlar, ancak hata ayıklama amaçları dışında açıklığa ihtiyaç duymazlar (yani yalnızca performans / kaynaklar üzerinde bir etki yarattıklarında onlara önem veriyorsunuz). Bu durumda DoThing ve DoThingAsync, diğer tempüle edilmiş algoritmalarla aynı durumdadır, açıklığa ihtiyaç duymazlar, ya desteklenirler ya da desteklenmezler ve sadece hata ayıklama için faydalıdırlar.
eocron

Farklı olan, async demek - arayan kişi bunu doğru şekilde yaptığınızdan emin olun. Görevi yeniden başlatma olgusu, yöntemin gerçekten Async olduğunu söylemek için yeterli değildir. Arayanın, aynı çıkış için GetAwaiter (). İşlerin içeride nasıl yapıldığı farklı değil.
madoxdev

Bu tamamen kod çözümleyicilerinin ve karşılaştırıcının amacıdır. IntellySense bunu sizin için kolayca işaret edebilir, senkronize olmayan kodda senkronize olmayan yöntem üzerinden senkronizasyon yöntemini vurgulamak veya hatta sürgün etmek için geliştirici beyinlerini kullanmaya gerek yoktur. Async kullanırken yaşadığım deneyimden nadiren GetResult () kullanmam gerekiyor, ancak sık sık kod tabanının tamamını Async ile kirletmem gerekiyor.
eocron

Birinin işaretlediği gibi - bu görüştür. İnandığımız şeye inanmaya devam edebiliriz ve mutlu oluruz :)
madoxdev
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.