2013-03-07 5 views
0
//I know for sure that the animal being passed is a Tiger 
protected virtual void Eat<AnimalType>(Animal animal) 
where AnimalType : Animal 
{ 
    //The animal type is a Tiger type. 
    //Should be equivalent to : 
    //Tiger myDerivedAnimal = animal as Tiger; 
    AnimalType myDerivedAnimal = animal as AnimalType; 

    if (myDerivedAnimal != null) 
    { 
     myDerivedAnimal.eat(); 
    } 
} 

내가 전화를 만들고있어 실패. 나는 디버거를 살펴 봤는데 인수로 전달 된 동물은 호랑이에 대한 참조가있는 동물이므로이 캐스팅이 내 호랑이를 돌려주지 않는 이유는 무엇입니까? 현재 myDerivedAnimal은 기본값 (0, null 등)으로 채워져 있습니다. 이 Animal을 상속하도록 제약 조건을 강제일반적인 방법은 명시 적 캐스트

protected virtual void Eat<AnimalType>(AnimalType animal) 
where AnimalType : Animal 

:

+0

'AnimalType : Animal'을 사용하여 제네릭을 잘못 사용하면'Animal' 만 얻습니다. – gdoron

+0

만약'animal as AnimalType'을 캐스팅했다면 메소드 시그니처를'protected virtual void Eat (AnimalType animal)으로 변경하는 것이 더 좋을 것입니다. AnimalType : Animal'? – MarioVW

답변

0

그것은 나를 위해 작동 : 나는 그것을 실행하면 예상대로

class Animal { 
    public virtual void eat() 
    { 
     Console.WriteLine("Animal.eat()"); 
    } 
    } 

    class Tiger : Animal { 
    public override void eat() 
    { 
     Console.WriteLine("Tiger.eat()"); 
    } 
    } 

    class SomethingElse { 

    protected virtual void Eat<AnimalType>(Animal animal) 
    where AnimalType : Animal 
    { 
     AnimalType myDerivedAnimal = animal as AnimalType; 

     if (myDerivedAnimal != null) 
     { 
      myDerivedAnimal.eat(); 
     } 
    } 

    public void Test() 
    { 
     var myTiger = new Tiger(); 
     Eat<Tiger>(myTiger); 
    } // Test 
    } 

    class Program { 
    static void Main(string[] args) 
    { 
     new SomethingElse().Test(); 
    } 
    } 

그것은

Tiger.eat() 

를 인쇄합니다.

+0

호기심에서 벗어난 이유는 무엇입니까? 제네릭이라면 오용을 전파한다는 점을 제외하면 이것은 에릭과 내가 말한 것입니다. 이것의 일반적인 부분은 결코 사용되지 않습니다 ... 나는 뭔가를 놓쳤습니까? –

+0

@ JustinPihony : 제 답변은 Eric과 똑같습니다. 코드가 실제로 작동한다는 것을 지적했습니다 (나는 대답을 얻지 못했습니다 ...). 나는 정확히 동일한 클래스 이름을 사용했다는 사실이 OP의 클래스 계층 구조가 어디에 문제가 있는지를 보여 주었다고 생각된다. – MiMo

7

이 아닌 제네릭이 작동하는 방법입니다, 당신은 더 이런 일을합니다. 매개 변수 유형이 Animal에서 AnimalType

으로 변경되었지만 여기에는 코드 외양으로 제네릭이 필요하지 않습니다. 당신은 루트에서 상속을 사용하고,이 자체가 일반에 의해 처리되는대로 캐스팅이 필요하지 않을 최소한 있도록 때문에 SO에 대한 단순화 될 수

animal.Eat() 

를 호출 할 수

내가 False있어

class P 
{ 
    class Animal {} 
    class Tiger : Animal {} 
    static void M<T> (Animal animal) where T : Animal 
    { 
     T t = animal as T; 
     System.Console.WriteLine(t == null); 
    } 
    static void Main() 
    { 
     Animal animal = new Tiger(); 
     M<Tiger>(animal); 
    } 
} 

:

+0

동의 -하지만 OP가 작성한 코드가 작동하지 않는 이유는 무엇입니까? – MiMo

+0

나는 변화를 만들었지 만 컴파일러가 AnimalType이 아닌 Animal을 기대하는 호랑이를 전달할 수는 없습니다. –

+0

타이거는 동물을 상속합니까? 그래서 당신은 @ 미모에 대답하기 위해 캐스트로 문제를 얻고있었습니다. 그것은 일반적인 제약의 요지입니다. 런타임 대신 컴파일 타임에이 문제를 잡을 수 있습니다. –

2

protected virtual void Eat<AnimalType>(AnimalType animal) 
    where AnimalType : Animal 
{ 
    if(animal == null) return; 
    animal.eat(); 
} 
나는이 코드를 시도했다. 따라서 귀하의 문제를 재현 할 수 없습니다. 설명하는 동작을 실제로 재현하는 작고 완벽한 프로그램을 제공하십시오. 그렇게하면 버그를 찾을 수 있습니다. 그렇지 않으면 실제로 분석 할 수있는 것을 알려줄 것입니다.

+0

나는 호랑이를 빠져 나가지 못하고있다. Animal() –

+0

@Pat 그럼 왜 타이거를 지나가고 있다는 것을 일반에게 말하는거야? 나는 정말로 당신이 제네릭을 더 잘 이해할 필요가 있다고 생각한다. ... –

+0

@ Pat : 그렇다면 "동물 호랑이"는 ​​거짓이어야하고 "호랑이 동물"은 null이어야합니다.호랑이가 아닌 동물이 호랑이라고 신고해야하는 이유는 무엇입니까? –

관련 문제