//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返回了我的null对象。我已经通过调试器看了一下,通过参数的动物是一只参考老虎的动物,那么为什么这个演员没能归还我的老虎?截至目前,myDerivedAnimal填充了默认值(0,null等)。
答案 0 :(得分:7)
这不是泛型如何工作,你想要更像这样的东西:
protected virtual void Eat<AnimalType>(AnimalType animal)
where AnimalType : Animal
约束将强制它,以便它继承Animal
。请注意,参数类型已从Animal
更改为AnimalType
但是,你甚至不需要通过代码的外观来提供泛型。您可以在其根目录中使用继承并调用
animal.Eat()
这可能是因为SO的简化,所以至少你不需要演员,因为这是由通用本身来处理的:
protected virtual void Eat<AnimalType>(AnimalType animal)
where AnimalType : Animal
{
if(animal == null) return;
animal.eat();
}
答案 1 :(得分: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
。因此,我无法重现您的问题。 提供一个小型,完整的程序,实际上可以重现您所描述的行为。您可以通过这样做找到您的错误,或者您将给我们实际分析的内容。
答案 2 :(得分: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()
正如所料。