문제

비슷한 요소와 독특한 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에서 클래스 파일을 생성하는 방법입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top