C #에서 다음 구조를 고려하십시오.
interface I1
interface I2
abstract class A
- class A1 : A
- class A11 : A1, I1
- class A12 : A1, I2
- class A2 : A
- class A21 : A2, I1
- class A22 : A2, I2
이제 생성자에서 인수를받는 클래스 B가 있습니다. 해당 인수는 A에서 파생되고 I2 인터페이스를 구현하는 클래스 여야합니다. 즉, A12 또는 A22 유형의 클래스 일 수 있지만 A11 또는 A21이 아닐 수 있습니다. 해당 매개 변수를 어떻게 정의 할 수 있습니까? 또한 매개 변수를 나중에 B에 속성으로 저장하고 싶습니다 (나중에 사용하기 위해).
A는 많은 가상 메소드를 제공하기 때문에 인터페이스로 재정의 할 수 없습니다. A1과 A2는 B가 아닌 다른 곳에서 사용되는 여러 특정 메서드를 제공하기 때문에 트리와 같은 상속 체계를 건너 뛸 수 없습니다. 그래서 제가 B에서 처리해야 할 것은 A와 I2의 것들입니다.
해당 매개 변수를 어떻게 정의 할 수 있습니까?
기본적으로 할 수 없습니다. 생성자가 아닙니다.
가장 가까운 방법은 B를 반환하는 정적 제네릭 메서드를 만드는 것입니다.
public static B CreateInstance<T>(T item) where T : A, I2
생성자는 제네릭이 될 수 없으므로 생성자에서이 작업을 수행 할 수 없습니다.
그러나 해당 값 을 저장 해야하는 경우 A
또는 유형의 필드를 선택하고 I2
필요할 때 캐스트해야합니다.
물론 B
Enigmativity의 대답에 따라 일반화 할 수 있지만 다른 의미가있을 수 있습니다. 비 제네릭을 원하면 B
잠재적으로 다음 두 가지를 모두 가질 수 있습니다.
public abstract class B
{
// Common operations which don't depend on the constructor parameter
}
public class B<T> : B where T : A, I2
{
public B(T item)
{
}
}
물론 이것은 꽤 복잡해지기 시작합니다.
양자 택일로, 당신은 할 수 컴파일 시간 검사를 건너 뛰고 바로 실행 시간에 확인 :
public class B
{
private readonly A item;
public B(A item)
{
if (!(item is I2))
{
throw new ArgumentException("...");
}
this.item = item;
}
}
일반적으로 컴파일 타임 안전이 선호 되지만이 경우에 수행해야하는 추가 작업을 수행 할 가치가 없을 수도 있습니다. 유형으로 무엇을하는지에 따라 다릅니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다