C # 5 가 비동기 프로그래밍을위한 모델 async
과 await
모델을 도입 한 후 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.ReadAllAsync 는
IAsyncEnumerable<T>
- EF Core 3에서 AsAsyncEnumerable ()
IAsyncEnumerable
을 호출 하면 결과가로 반환됩니다. - System.Linq.Async에서 ToAsyncEnumerable ()은 IEnumerables, Tasks 및 Observables를
IAsyncEnumerable
s 로 변환 합니다. - 다른 모든 운영자는
System.Linq.Async
자신의 이름 을 유지합니다. 아무 없습니다SelectAsync
또는SelectAsAsyncEnumerable
그냥Select
.
모든 경우에, 방법의 결과가 무엇인지는 분명하다. 모든 경우에, 방법의 결과는 사용 await foreach
되기 전에 기다려야 합니다.
따라서 실제 지침은 동일 하게 유지됩니다. 이름으로 인해 동작이 명확 해집니다 .
- 이름이 이미 명확
AsAsyncEnumerable()
하거나 예를 들어ToAsyncEnumerable()
또는가있는 경우 접미사를 추가 할 필요가 없습니다. - 다른 경우에는
Async
접미사를 추가하십시오. 개발자await foreach
가 결과에 필요한 것을 알 수 .
코드 분석기와 생성기는 실제로 메소드 이름을 신경 쓰지 않고 코드 자체를 검사하여 냄새를 감지합니다. 코드 분석기는 작업을 기다리는 것을 잊었 음을 알려주거나await foreach
을 IAsyncEnumerable
상관없이 방법과 변수를 호출하는 방법. 발전기는 단순히 반사를 사용하여 확인 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 와 같은 다른 접미사가 필요할 것입니다 . 그렇지 않으면 불평합니다. 똑같은 방법이지만 다른 방식으로 작동합니다. 다형성처럼. 인터페이스처럼.