제네릭 기본 클래스에서 상속하고 제약 조건을 적용하고 C #에서 인터페이스 구현


117

이것은 구문 질문입니다. 제네릭 기본 클래스에서 상속되고 형식 매개 변수 중 하나에 제약 조건을 적용하는 제네릭 클래스가 있습니다. 또한 파생 클래스가 인터페이스를 구현하기를 원합니다. 내 인생에서 올바른 구문을 알아낼 수없는 것 같습니다.

이것이 내가 가진 것입니다.

DerivedFoo<T1,T2> : ParentFoo<T1, T2> where T2 : IBar { ... }

가장 먼저 떠오른 것은 다음과 같습니다.

DerivedFoo<T1,T2> : ParentFoo<T1, T2> where T2 : IBar, IFoo { ... }

그러나 이는 T2가 IBar와 IFoo를 모두 구현해야하므로 DerivedFoo가 IFoo를 구현하는 것이 아니기 때문에 올바르지 않습니다.

나는 약간의 인터넷 검색, 콜론, 세미콜론 사용 등을 시도했지만 짧게 나타났습니다. 대답은 매우 간단합니다.


한 번봤을 때 @Adam의 대답을 이해할 수 없었지만 2 분 후에 나는 그것이 무엇인지 알 수있었습니다. 대답 해 주셔서 감사합니다. 파생 된 클래스는 하나 이상의 구현을 가지고있을 수 있습니다. 어쨌든 다른 사람들에게 그 표기법을 보여주고 싶습니다. "class DerivedClass <Type> : ParentClass where Type : IType". 마지막으로 구현 된 클래스와 where 절 사이에는 아무것도 없어야합니다.
nurisezgin

답변:


173

일반 제약 조건을 정의하기 전에 클래스의 전체 서명을 포함합니다.

class DerivedFoo<T1, T2> : ParentFoo<T1, T2>, IFoo where T2 : IBar
{
    ...
}

5
다른 사람들에게는 클래스가 하나의 where 절만 가져오고 모든 제네릭 유형 제약 조건에 대해 끝에 간다.
Andy V

@Visser 여러 where 절을 가질 수 있습니다. 클래스 Test <T1, T2> where T1 : Interface1 where T2 : Interface2
bwing

@Visser 예, bwing이 말한 것, 또한 각 where 절은 여러 제약 조건을 가질 수 있습니다. 따라서 원래 게시물의 구문이 정확합니다. 단지 op가 원하는 것과 다른 것을 의미합니다. where T2 : IBar, IFoo 단지 수단 T2대신 두 인터페이스를 구현하는 DerivedFoo<T1,T2> 구현IFoo
v01pe

18

내 추천 : C # 언어의 구문에 대한 질문이 있으면 사양을 읽으십시오. 그것이 우리가 그것을 출판하는 이유입니다. 섹션 10.1을 읽고 싶을 것입니다.

특정 질문에 답하기 위해 클래스 선언의 순서는 다음과 같습니다.

  • 속성, 대괄호 안에
  • 수정 자 ( "공용", "정적"등)
  • "일부"
  • "수업"
  • 클래스 이름
  • 꺾쇠 괄호 안에 쉼표로 구분 된 유형 매개 변수 선언 목록
  • 콜론 뒤에 쉼표로 구분 된 기본 유형 목록 (기본 클래스 및 구현 된 인터페이스가있는 경우 기본 클래스가 먼저 가야 함)
  • 유형 매개 변수 제약
  • 중괄호로 둘러싸인 클래스 본문
  • 세미콜론

해당 목록의 모든 항목은 "클래스", 이름 및 본문을 제외하고 선택 사항이지만 표시되는 경우 모든 항목이 해당 순서로 나타나야합니다.


95
Eric, 전문가로서 귀하를 매우 존경하고 귀하의 피드백에 감사 드리지만, 혹독한 답변으로 나타나는 것에 실망 할 수밖에 없습니다. MSDN의 링크에 묻혀있는 고도로 기술적 인 503 페이지 Word 문서를 찾고, 다운로드하고, 검색하는 것보다 프로그래밍 Q & A 사이트에서 질문을하기로 결정한 것에 대해 저를 비판하고 있습니다. 꽤 거칠다. 이것은 내 시간을 가장 효율적으로 사용했으며 나중에 다른 사람에게 도움이 될 수있는 추가적인 이점이 있습니다. 관심있는 사람들을위한 C # 언어 사양 링크 : msdn.microsoft.com/en-us/vcsharp/aa336809.aspx
Dan Rigby

17
비판은 의도되지 않았습니다. 단순한 사실 진술을 무자비하고 거친 소리로 만드는 순수한 텍스트 의사 소통에는 편견이 있습니다. 나는 도움이되는 사실의 목록을 제시 할 때 자선 적으로 읽으려고 노력하고 당신도 그렇게 할 것을 권장합니다. 나는 나의 추천을지지한다. 구문에 대한 질문이있는 경우 사양은 명확하게 답변하고 특정 구문의 정의를 찾는 데 도움이되는 목차로 시작합니다.
Eric Lippert

3
Dan, C # 사양을 찾는 것은 Google에 'C # Spec'을 입력하고 'I am lucky'버튼을 누르는 것만 큼 간단합니다. 전문 C # 개발자 인 경우 컴퓨터에 PDF 형식의 C # 사양이 이미 있어야합니다. 또한 당신을 비판하는 것도 아닙니다. 이전에는 사양을 읽는 데 익숙하지 않았지만 질문에 대해 항상 C # 사양을 인용하는 Jon, Eric 및 Pavel 덕분에 읽기 시작했습니다. 때때로 읽기 어려울 수 있지만 C # 사양은 언어에 대해 배우는 좋은 방법이라는 것을 알았습니다.
SolutionYogi

@Eric Lippert : 충분합니다. 당신의 답변에 감사드립니다. 건설적인 제안으로 Microsoft가 사양의 내용을 MSDN에 직접 통합하고 별도의 다운로드로 존재하도록하는 것이 도움이 될 것입니다. Visual Studio .Net MSDN 버전에는 사양의 통합 버전이 있지만 이후 버전은 없습니다. 나는 Anders Hejlberg의 책을 구매할 생각을했지만 .Net 4.0이 다가 오면 아직 꺼려합니다. amazon.com/C-Programming-Language-3rd/dp/0321562992 감사합니다.
Dan Rigby

2
C ++ 에서는 클래스 선언이 세미콜론으로 끝나야합니다. 많은 C # 개발자는 C ++ 배경에서 왔습니다. 때때로 그들의 손가락은 두뇌가 개입하지 않고 세미콜론을 삽입합니다. :-) C #에는 C ++에서 하나가 필요한 세미 옵션을 사용하는 여러 구문이 있습니다. 그것은 미묘한 편의에 불과합니다. 유형 선언이 끝날 때 미묘하게 호출 할 수 있고 메서드 본문 선언을 말할 수도 있다고 가정합니다.
Eric Lippert

8
public interface IFoo {}
public interface IBar {}

public class ParentFoo<T,T1> { }
public class DerivedFoo<T, T1> : ParentFoo<T, T1>, IFoo where T1 : IBar { }

2
public class KeyAndValue<T>
{
    public string Key { get; set; }
    public virtual T Value { get; set; }
}

public class KeyAndValue : KeyAndValue<string>
{
    public override string Value { get; set; }
}

이것은 기존 답변의 확장입니다. string유형을 제공하지 않으면 기본값으로 설정 됩니다. 나는 인터페이스를 구현하지 않았지만 평소와 다른 것을 요구해서는 안됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.