인터페이스로 정의 된 것처럼 클래스를 처리하십시오.
-
19-08-2019 - |
문제
비슷한 요소와 독특한 100 개의 클래스가 있습니다. 나는 비슷한 항목과 같은 인터페이스를 만들었습니다 : 인터페이스 ianimal. 내가 평소에 할 일은 다음과 같습니다.
class dog : IAnimal
그러나 100 개의 수업이 있으며 나는 그들 모두를 가고 Ianimal을 적용 할 수있는 수업을 찾고 싶지 않습니다.
내가하고 싶은 것은 이것입니다 :
dog scruffy = new dog();
cat ruffles = new cat();
IAnimal[] animals = new IAnimal[] {scruffy as IAnimal, ruffles as IAnimal} // gives null
또는
IAnimal[] animals = new IAnimal[] {(IAnimal)scruffy, (IAnimal)ruffles} //throws exception
그럼
foreach (IAnimal animal in animals)
{
animal.eat();
}
C#을 쓰지 않아도 주름과 멍청한 것을 Ianimal으로 취급 할 수있는 방법이 있습니까?
감사!
편집 (게으르지 않음) : 클래스는 SQL 저장된 Proc Metadata에서 생성됩니다. 즉, 생성 될 때마다 다시 가서 추가해야한다는 것을 의미합니다. 실제로 그것은 나쁜 생각이 아닙니다. 나는 일종의 제네릭 접근법이나 무언가가 있기를 바랐다.
해결책
이 문제를 해결할 수 있습니다 부분 수업: 기계 생성/재생 코드를 각 클래스의 한 소스 파일과 손으로 구분 된 부분 (Ianimal에서 서브 클래싱 정의)으로 두십시오.
다른 팁
당신이 요구하는 것은 오리 타이핑이라고하며 C#의 일부가 아닙니다. 모든 솔루션에는 반사가 포함되고 속성을 살펴보면 수업을 손으로 확인하는 것이 더 빠릅니다.
그래도 시도하는 흥미로운 프로젝트 일 것입니다.
솔루션은 코드 생성기를 수정하는 것입니다. 현재 귀하의 요구에 너무 단순합니다. 관련 속성 및/또는 메소드가 클래스에있는 경우 인터페이스 구현을 추가해야합니다.
액세스하는 어댑터를 만들 수 있습니다. "eat
"반사를 통해 가난한 사람의 오리 타이핑 :
public class Adapter<T> : IAnimal
{
private T x;
Adapter(T x)
{
this.x = x;
}
public void eat()
{
x.GetType().GetMethod("eat").Invoke(this);
}
}
그런 다음 다음과 같이 사용할 수 있습니다.
dog scruffy = new dog();
cat ruffles = new cat();
IAnimal[] animals = new IAnimal[] {new Adapter<dog>(scruffy), new Adapter<cat>(ruffles )};
내가 알고있는 쉽지 않은 것은 반사를 사용하여 늦은 바인딩 호출을 할 수 있지만 수업을 편집하는 데 시간을 보내거나 매크로를 작성하는 것이 좋습니다.
당신이 정말로 좋은 이유로 CAT 클래스를 수정할 수 없다고 가정하면
Ianimal IE에서 상속 된 고양이의 어댑터를 쓸 수 있습니다.
class cat_adapter : IAnimal
{
private cat baseCat;
public cat_adapter( cat aCat)
{
baseCat = aCat;
}
// Implement IAnimal interface and redirect to baseCat
public void eat()
{
baseCat.munchOnMeowMix();
}
}
C ++에서는 생성 된 모든 클래스가 동일한 기능을 가져야한다고 가정 할 때 템플릿을 사용할 수 있습니다.
template <class BaseType>
class CAnimalAdapter : public IAnimal
{
private:
BaseType* m_baseInstance;
public:
CAnimalAdapter(BaseType* baseInstance) :
m_baseInstance(baseInstance)
{
}
void eat()
{
// You will get a compiler error if BaseType doesn't have this implemented
baseInstance->doEat();
}
}
아마도 나보다 더 c#--py가 반사로 똑같이 할 수 있습니다.
코드 생성기가 클래스를 부분적으로 생성하는 경우 인터페이스를 구현하는 다른 부분 정의를 추가 할 수 있습니다.
아니요. 콘크리트베이스 클래스가 있거나 인터페이스가 없으면 C#을 얻을 수있는 방법이 없습니다.
클래스는 인터페이스 Ianimal을 구현해야합니다. 두 개의 다른 클래스에서 동일한 이름의 메소드/속성은 인터페이스/기본 클래스의 구현이 아니라면 동등한 것으로 간주되지 않습니다.
메소드를 이미 구현 한 적이 있고 인터페이스를 구현하려는 경우 IDE에서 Files in Files 명령으로 정규식을 사용할 수 있습니다.
그렇지 않으면 확장 방법을 살펴보십시오. 그들은 당신의 필요에 맞을 수 있습니다.
생성 된 클래스를 부분 클래스로 구현하는 경우이 클래스의 인터페이스를 구현 한 다음 코드 생성기를 변경하여 부분 클래스의 절반 만 생성 할 수 있습니다. 이를 통해 인터페이스 구현을 잃지 않고 클래스를 재생할 수 있습니다 (또는 추가하기로 결정한 다른 사용자 지정 로직).
이러한 유형의 접근 방식은 LINQ에서 SQL에서 클래스 파일을 생성하는 방법입니다.