찾고있는 소리가 template this parameters입니다.
class Base { T[] sequence(this T)() { return null; } }
class Derived : Base {}
static assert(is(typeof((new Derived).sequence()) == Derived[]));
참고 그러나, sequence
는 상기 템플릿이 상기베이스 클래스의 컨텍스트에서 인스턴스화 것이 가상 함수 아니며,. 사용자에게 간단한 인터페이스를 제공하려면 특수 기능으로 전달해야 할 수 있습니다. 가상 호출이 가장 매혹적인 보일 수 있습니다
class Base {
T[] sequence(this T)() {
// Virtual call, requires unsafe cast of return type.
return cast(T[])sequenceImplVirtual();
// Non-virtual call, requires safe cast of this reference
// and will fail if the subclass doesn't implement it correctly.
return (cast(T)this).sequenceImplDuck();
}
abstract Base[] sequenceImplVirtual();
}
class Derived : Base {
Derived[] sequenceImplDuck() {
return [this];
}
override Base[] sequenceImplVirtual() {
return [this];
}
}
unittest {
Derived[] arr = (new Derived).sequence;
}
, 등이 중 하나를 (당신이 함수의 반환 값을 캐스팅 할 필요가있는 경우) 가상 함수 또는 서브 클래스에 오리 - 입력 기능을 할 수있다 하위 클래스가 sequenceImplVirtual
을 구현하지 못하면 컴파일 오류가 발생합니다. 그러나 무시 함수가 Derived[]
을 반환한다고 주장하지 않으며 실수로 Base
또는 Derived
에서 파생되지 않은 다른 클래스를 반환하면 프로그램이 분리됩니다. 명시 적 캐스트는이를 효과적으로 숨 깁니다. 약간 더 자세한 프로그램은이 테스트 수 :
T[] sequence(this T)() {
import std.algorithm.searching : all;
auto result = sequenceImplVirtual();
assert(result.all!((Base a) => a is null || cast(T)a !is null));
return cast(T[])result;
}
이것은이 sequenceImplVirtual
잘못된 값을 반환하는 경우 런타임에 오류를 주장 알기 쉬운 줄 것이다.
오리 형 솔루션은 다른 사용자가 사용하기 전까지 sequenceImplDuck
을 구현하는 것을 잊지 않았다는 의미는 아닙니다. 그것은 단지 안전 캐스트 (cast(T)this
를) 수행으로 인해 그러나, 컴파일러 보장 반환 값은 참으로 Derived[]
입니다 :
class Base {
T[] sequence(this T)() {
return (cast(T)this).sequenceImplDuck();
}
}
class Derived : Base {
// Note: wrong return type.
// Will fail to compile when you call sequence().
Base[] sequenceImplDuck() {
return [this];
}
}
class Derived2 : Base {
// Note: No implementation.
// Will fail to compile when you call sequence().
}
unittest {
Derived[] arr = (new Derived).sequence;
auto d = new Derived2;
auto arr2 = d.sequence;
}
위는 유닛 테스트를 주석 경우 -unittest
컴파일 할 때 실패 할 것이지만, 또는 -unittest
없이 컴파일하면 컴파일러는 Derived
또는 Derived2
이 가상 호출이 필요한 함수를 올바르게 구현하지 않는다는 표시를 제공하지 않습니다.
자식 클래스가 많이 있고 기본 클래스의 유형이 모두 들어있는 목록이있는 경우 각 요소에 대해'sequence'가 무엇을 반환 할 것으로 기대합니까? 각각 다른 유형? 그것은 정적 타이핑이 작동하는 방식이 아닙니다. 비록 당신이 표준 다형성 수단을 사용하여 원하는 것을 얻을 수있을지라도. 실제로 무엇을하고 싶습니까? – weltensturm
글쎄,이게 내가하고 싶은 일이 아니지만, 설명을 위해서 작동한다. XMLElement와 JSONElement가 상속받은 SerializedElement와 같은 추상 클래스가 필요하다고 해봅시다. 나는 각 자식 클래스에 자식 요소를 반환하기위한 메서드/속성을 갖고 싶습니다. 자식 요소는 분명히 같은 클래스에 속할 것입니다. 어떻게하면 (심지어 가능하다면) 자식 (XMLElement 또는 JSONElement) 유형의 배열을 반환하는 SerializedElement의 추상 메서드를 구현할 수 있습니까? –