2014-09-11 6 views
0

최근 코드를 작성하는 동안이 문제가 발생했습니다. 유형을 기반으로 올바른 확장 방법을 식별 할 수 있도록 기본 클래스에 코드를 작성할 수있는 방법이 있습니까?제네릭 클래스 메서드에 대한 올바른 확장 메서드를 얻는 방법?

namespace GenericsInheritance 
{ 
    public class Animal { } 

    public class Dinasaur : Animal { } 

    public class Dragon : Animal { } 

    public abstract class Zoo<T> where T : Animal 
    { 
     public virtual string IdentifyYourSelf(T record) 
     { 
      //Calling extension method 
      string name = record.IdentifyYourSelf(); 
      return name; 
     } 
    } 

    public class DinasaurZoo : Zoo<Dinasaur> 
    { 
     //I could use this, just wanted to try if base class method does identify the correct extension method for the type. 
     //public override string IdentifyYourSelf(Dinasaur record) 
     //{ 
     // return record.IdentifyYourSelf(); 
     //} 
    } 

    public class DragonZoo : Zoo<Dragon> { } 

    public class AnimalZoo : Zoo<Animal> { } 

    //Extensions methods class. 
    public static class LieDetector 
    { 
     public static string IdentifyYourSelf(this Animal record) { return "Animal"; } 

     public static string IdentifyYourSelf(this Dinasaur record) { return "Dinasaur"; } 

     public static string IdentifyYourSelf(this Dragon dog) { return "Dragon"; } 

     //It works if I use this. 
     //public static string IdentifyYourSelf<T>(this T record) where T : Animal 
     //{    
     // if (record is Dinasaur) { var dinasaur = record as Dinasaur; return IdentifyYourSelf(dinasaur); } 
     // else if (record is Dragon) { var dragon = record as Dragon; return IdentifyYourSelf(dragon); }   
     // else return "I do not exist"; 
     //} 
    } 

    public class FbiInterrogation 
    { 
     public static void Main(string[] args) 
     { 
      var animal = new Animal(); 
      var dinasaur = new Dinasaur(); 
      var dragon = new Dragon(); 
      var dinasaurZoo = new DinasaurZoo(); 
      var dragonZoo = new DragonZoo(); 
      var animalZoo = new AnimalZoo(); 

      string name = dinasaurZoo.IdentifyYourSelf(dinasaur); //Prints Animal expecting Dinasaur 
      name = dragonZoo.IdentifyYourSelf(dragon); //Prints Animal expecting Dragon 
      name = animalZoo.IdentifyYourSelf(animal); //Prints Animal 

      Console.ReadKey(); 
     } 
    } 
} 
+2

확장 방법이 해결 그들이있어하는 변수의 정적 유형에 따라 : 나는 그렇게하는 것이 좋은 생각인지 모르겠어요하지만 – phoog

+0

고마워요 .-) –

+0

오버로드 또는 오버라이드 하시겠습니까? –

답변

2

확장 메서드는 호출되는 변수의 정적 유형 (런타임 유형이 아님)에 따라 결정됩니다. 그래서 귀하의 질문에 대한 대답은 "아니오"입니다. 파생 된 클래스의 재정의 또는 성가신 형식 검사를 통해 문제를 해결해야합니다.

public abstract class Zoo<T> where T : Animal 
{ 
    public virtual string IdentifyYourSelf(T record) 
    { 
     return typeof(LieDetector).GetMethod("IdentifyYourSelf", new[] {typeof(T)}, null).Invoke(record, new object[] {record}) as string; 
    } 
} 
0

실제로 반사를 사용하여 얻을 수있는 실행 시간 유형이 아니라 호출됩니다. 그래서 귀하의 질문에 대한 대답은 "아니오"입니다 - 파생 된 클래스에서 오버로드를 통해이를 수행해야합니다.
관련 문제