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

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 또는 기타 기관에서 제공)이 있습니까?



답변

.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

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

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


답변

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

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


답변

비동기 접미사 및 키워드조차도 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 와 같은 다른 접미사가 필요할 것입니다 . 그렇지 않으면 불평합니다. 똑같은 방법이지만 다른 방식으로 작동합니다. 다형성처럼. 인터페이스처럼.


답변