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();
   }
}

当我打电话时:

Eat<Tiger>(anAnimalThatIsATiger);

由于某种原因, as cast 正在返回我的空对象。我查看了调试器,传入参数的动物是引用老虎的动物,那么为什么这个演员无法返回我的老虎?截至目前,myDerivedAnimal 填充了默认值(0、null 等)。

4

3 回答 3

7

这不是泛型的工作方式,你想要更像这样的东西:

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

约束将强制它继承Animal. 请注意,参数类型从更改AnimalAnimalType

但是,从代码的外观来看,您甚至不需要泛型。您可以在其根部使用继承并调用

animal.Eat()

这可能是因为 SO 的简化,所以至少你不需要演员表,因为这是由泛型本身处理的:

protected virtual void Eat<AnimalType>(AnimalType animal)
    where AnimalType : Animal
 {
   if(animal == null) return;
   animal.eat();
}
于 2013-03-07T19:25:30.910 回答
2

我试过这段代码:

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);
    }
}

我得到了False。因此,我无法重现您的问题。提供一个小而完整的程序,它可以实际重现您所描述的行为。要么你会通过这样做找到你的错误,要么你会给我们一些我们可以实际分析的东西。

于 2013-03-07T19:39:08.477 回答
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()

正如预期的那样。

于 2013-03-07T19:45:14.467 回答