通用方法失败显式转换

时间:2013-03-07 19:24:16

标签: c#

//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等)。

3 个答案:

答案 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()

正如所料。