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 キャストが null オブジェクトを返しています。デバッガーを調べたところ、引数に渡された動物は虎を参照する動物であるのに、なぜこのキャストが私の虎を返さないのでしょうか? 現在、myDerivedAnimal にはデフォルト値 (0、null など) が入力されています。

4

3 に答える 3

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();
}
于 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 に答える