IAsyncEnumerable을 반환하는 메서드에 대한 명확한 명명 규칙이 있습니까?


10

C # 5 가 비동기 프로그래밍을위한 모델 asyncawait모델을 도입 한 후 C # 커뮤니티는 명명 규칙에 도달하여 다음과 같이 대기 가능한 유형을 리턴하는 메소드에 "Async"접미 부를 추가합니다.

interface Foo
{
   Task BarAsync();
}

많은 정적 코드 분석기 (Roslyn 기반 및 비 Roslyn 기반)는 비동기 프로그래밍에서 코드 냄새를 감지 할 때이 명명 규칙에 따라 작성되었습니다.

C # 8에서 비동기 열거 형 개념을 도입 했으므로 이제는 기다릴 수 없지만 함께 사용할 수있는 await foreach메서드를 반환하는 두 가지 옵션이있는 것 같습니다 IAsyncEnumerable.

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

또는

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

C # 5 명명 규칙이 명확하게 표준화되고 의견에 근거한 프로그래머의 판단에 의존하지 않는 방법과 같은 위의 옵션에 대한 명확한 명명 규칙 지침 (C # 언어 팀, .NET Foundation 또는 기타 기관에서 제공)이 있습니까?


2
옵션 2는이 코드를 비동기 적으로 실행하고 (메소드를 표시 async하고 await내부에서 사용 ) msdn 샘플 이 동일하게 표시되므로 여기에서 올바른 소리가 납니다.
Pavel Anikhouski

1
질문의 종결에 대한 응답으로 결정적인 명명 규칙이 존재하는지 묻고 C # 5의 결정적인 명명 규칙이 정적 코드 분석에서 어떻게 발전했는지 예를 들기 위해 질문을 편집했습니다. 따라서 C # 8이이 패턴을 따르게되면 의견 기반 코딩 환경 설정을 넘어서서 측정 가능한 코드 품질이 향상됩니다.
hwaien

.NET 코어 자체는 사용 Async방법이 반환 접미사를 IAsyncEnumerable, 예를 들어, ChannelReader.ReadAllAsync . 다른 경우에는, EF 코어의 예를 들면, AsAsyncEnumerable()이미 분명하다하는 데 사용됩니다
파나지오티스 Kanavos에게

인간이 코드를 이해하기 쉽도록 명명 지침이 있습니다. 코드의 목적이 명확하지 않으면 접미사를 추가하십시오.
Panagiotis Kanavos

답변:


1

.NET 팀이 이미 하는 것보다 더 나은 지침은 없습니다 .

  • ChannelReader.ReadAllAsyncIAsyncEnumerable<T>
  • EF Core 3에서 AsAsyncEnumerable ()IAsyncEnumerable 을 호출 하면 결과가로 반환됩니다.
  • System.Linq.Async에서 ToAsyncEnumerable ()은 IEnumerables, Tasks 및 Observables를 IAsyncEnumerables 로 변환 합니다.
  • 다른 모든 운영자는 System.Linq.Async자신의 이름 을 유지합니다. 아무 없습니다 SelectAsync또는 SelectAsAsyncEnumerable그냥 Select.

모든 경우에, 방법의 결과가 무엇인지는 분명하다. 모든 경우에, 방법의 결과는 사용 await foreach되기 전에 기다려야 합니다.

따라서 실제 지침은 동일 하게 유지됩니다. 이름으로 인해 동작이 명확 해집니다 .

  • 이름이 이미 명확 AsAsyncEnumerable()하거나 예를 들어 ToAsyncEnumerable()또는가있는 경우 접미사를 추가 할 필요가 없습니다.
  • 다른 경우에는 Async접미사를 추가하십시오. 개발자await foreach 가 결과에 필요한 것을 알 수 .

코드 분석기와 생성기는 실제로 메소드 이름을 신경 쓰지 않고 코드 자체를 검사하여 냄새를 감지합니다. 코드 분석기는 작업을 기다리는 것을 잊었 음을 알려주거나await foreachIAsyncEnumerable상관없이 방법과 변수를 호출하는 방법. 발전기는 단순히 반사를 사용하여 확인 IAsyncEnumerable하고 방출 할 수 있습니다.await foreach

그건 이름을 확인 스타일 분석기입니다. 그들의 임무는 개발자 가 코드를 이해할 수 있도록 코드가 일관된 스타일을 사용하도록하는 것 입니다. 스타일 분석기는 분석법이 선택한 스타일을 따르지 않는다고 알려줍니다. 이 스타일은 팀 또는 일반적으로 인정되는 스타일 가이드 일 수 있습니다.

물론 개인 인스턴스 필드의 공통 접두사는 다음과 같습니다. _:)


ChannelReader.ReadAllAsync예제 를 지적 해 주셔서 감사합니다 . 이것은 .NET 팀에서 직접 제공되므로 소송에 따라 잘못 가기가 어렵습니다.
hwaien

분석기 패키지는 종종 스타일 및 비스타 일 분석기의 혼합 백과 함께 제공됩니다. 예를 들어, Microsoft.VisualStudio.Threading.Analyzers 패키지에는 명명 규칙 (VSTHRD200)을 확인하는 스타일 분석기와 교착 상태로 이어질 수있는 위험한 상황을 감지하는 비스타 일 분석기 (VSTHRD111)가 있습니다. VSTHRD111을 활용하기 위해 패키지를 참조하기 위해 프로젝트는 VSTHRD200으로 끝납니다.
hwaien

2

비동기 메서드가 아니므로 이름이 'Async'로 끝나서는 안됩니다. 이 메소드 접미사는 메소드를 기다리거나 결과를 태스크로 처리해야한다는 것을 분명히하기위한 규칙입니다.

나는 일반적인 컬렉션 반환 이름이 적절하다고 생각합니다. GetFoos () 또는 이와 유사합니다.


그것들은 모두 접미사 사용하는 인수 입니다Async . 접미사는 .NET Core 자체에서 사용됩니다. ChannelReader.ReadAllAsyncIAsyncEnumerable을 반환합니다. 는 IAsyncEnumerable함께 사용할 수있다 await foreach접미사가 의미가 있도록.
Panagiotis Kanavos

1

비동기 접미사 및 키워드조차도 async상용구이며, 이전 버전과의 호환성 인수 외에는 의미가 없습니다. C #에는 다음과 같은 것을 추가 할 필요가 없다는 것을 알기 때문에 yield반환하는 메소드 와 구별 되는 것처럼 해당 함수를 구별하는 모든 정보 IEnumerable가 있습니다.enumerable 이러한 메서드에 하거나 다른 키워드 있습니다.

C #이 과부하에 대해 불평하기 때문에 비동기 접미사 를 추가해야 하므로 본질적 으로이 두 가지는 동일하며 모든 다형성 규칙에 따라 동일한 일을 수행합니다 (인간적으로 행동을 손상시키는 인적 요소를 고려하지 않는 경우).

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

그러나 컴파일러가 불평하기 때문에 이렇게 작성할 수 없습니다. 그러나 이봐! 이 괴물을 삼킬 것입니다.

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

그리고 이것조차도 :

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

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

이게 다야. 컴파일러가 불평하도록 중지하기 위해 비동기를 추가 합니다. 명확하게하지 말아야합니다. 더 나아지지 않기 위해. 불만이 없으면 추가 할 이유가 없으므로 귀하의 경우에는 이것이되지 않는 한 이것을 피할 것 Task<IAsyncEnumerable>입니다.

추신 : 여기에 전체 그림을 더 잘 이해하기 위해-언젠가 누군가가 다른 패러다임에서 작동 할 C # 퀀텀 컴퓨터 메서드 확장 (판타지, 허)을 추가하는 경우 아마도 Quant 와 같은 다른 접미사가 필요할 것입니다 . 그렇지 않으면 불평합니다. 똑같은 방법이지만 다른 방식으로 작동합니다. 다형성처럼. 인터페이스처럼.


1
미안하지만, 나는 동의하지 않는다고 생각합니다. 실제로 같은 일을하는 다른 접근법은 아닙니다. 그것은 비동기와 비 비동기의 가장 큰 차이점입니다. 나는 비동기를 추가하는 것이 명확함을 강력히 믿는다. 이것이 또한 Microsoft의 권장 사항이라고 생각합니다.
madoxdev

예, 동의하지만 동의하지 않습니다. List와 마찬가지로 "QuickSort", "RadixSort", "BubbleSort", "MixOfSorts"가 아닌 간단한 정렬 기능이 있습니다. 그것들은 범위에 따라 다르지만 디버깅 목적 이외의 명확한 설명이 필요하지 않습니다 (성능 / 자원에 영향을 줄 때만 신경 쓰십시오). 이 경우 DoThing 및 DoThingAsync는 다른 템플릿 알고리즘과 동일한 상황에 있으며 설명이 필요하지 않으며 지원 여부에 관계없이 디버깅에만 유용합니다.
eocron

그것은 다른 비동기 수단입니다-heu 발신자는 이것을 올바르게 처리해야합니다. 폐기 작업의 사실은 그 방법이 진정 비동기라고 말하기에는 충분하지 않습니다. 호출자는 동일한 생략을 얻기 위해 대기하거나 GetAwaiter (). GetResilt ()를 사용해야합니다. 내부에서 작업이 수행되는 방식이 다릅니다.
madoxdev

이것은 전적으로 코드 분석기와 컴파일러의 목적입니다. IntellySense는 비동기 코드에서 비동기 방식보다 동기화 방식을 강조하거나 사용하지 않기 위해 개발자의 두뇌를 사용하지 않아도 쉽게 지적 할 수 있습니다. 비동기를 사용할 때의 경험으로는 GetResult ()를 거의 사용하지 않아도되지만 Async로 전체 코드베이스를 자주 오염시켜야합니다.
eocron

누군가가 그것을 표시했듯이-그것은 의견입니다. 우리는 우리가 믿는 것과 행복을 믿을 수 있습니다. :)
madoxdev
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.