6

次のクラスがあるとします。

class Animal
{
    public long Id { get; set; }
    public string Name { get; set; }
}

class Dog:Animal
{
    public void sniffBum()
    {
        Console.WriteLine("sniff sniff sniff");
    }
}

のインスタンスがある場合、Animalそれを にキャストするにはどうすればよいDogですか? このようなもの:

Animal a = new Animal();
if ( some logic to determine that this animal is a dog )
{
    Dog d = (Dog)a;
    d.sniffBum();
}

基本的に、インターフェイスを使用できません。そのように、データベースから常にAnimalオブジェクトが出てきます。Dog持っている以上のパラメータはAnimalなく、新しいメソッドだけです。

新しいDogオブジェクトを作成して値を渡すこともできますが (または type を受け取るコンストラクターを使用することもできますAnimal)、これは面倒です。

4

10 に答える 10

3

オブジェクトを型にキャストできるかどうかを確認するには、isキーワードを使用します。

Animal animal = new Dog();

if( animal is Dog)
{
    //your code
}
于 2013-04-25T12:47:36.287 に答える
3

最初に動物を犬として作成し、それ isが犬かどうかを確認します

Animal a = new Dog();
if (a is Dog )
{
   Dog d = (Dog)a;
   d.sniffBum();
}
于 2013-04-25T12:49:45.463 に答える
2

Animalインスタンスがインスタンスになったことがない場合、キャスト チェックは機能しませんDog

インスタンスにメソッドを追加できるようにするDecorator Patternを参照してください。基本的に、両方にインターフェースがあります。クラスはコンストラクターでインスタンスを受け取り、内部参照を保持します。の実装は、それが参照するインスタンスに従うだけです (これにより、がキャストされ、ポリモーフィズムのためにラップされたように動作することが可能になります)。には、Dog 固有の追加メソッドもあります。DogAnimalDogAnimalIAnimalDogAnimalDogIAnimalAnimalDogIAnimalAnimalDog

于 2013-04-25T12:57:09.523 に答える
2

でそれを行うことができますがis、任意の犬で何かを呼び出したいので、使用する方が良いでしょうas:

var dog = a as Dog;
if (dog != null)
{
    dog.sniffButt();
}

ただし、この配置 (値の実行時の型を決定して、便利な値にキャストできるようにすること) は、通常、正当な理由で嫌われていることに注意してください。簡単にやりすぎて、犬、猫、オウム、魚、カメをチェックすることになる可能性があります.結果として生じる混乱を視覚化できると確信しています.

ニーズがそのシナリオを指している場合、はるかに優れたソリューションは、ビジター デザイン パターンを使用することです。

于 2013-04-25T12:49:21.747 に答える
1

動物は決して犬になることはできません。

Animal をパラメーターとして取り、Dog コンストラクターを作成します。

class Dog : Animal
{
   public Dog(Animal a)
   {
      this.Name = a.Name;
      this.Id = a.Id;
   }

   public void sniffBum()
   {
       Console.WriteLine("sniff sniff sniff");
   }
}
于 2013-04-25T12:59:50.727 に答える
0

動物を犬にキャス​​トすることはできません。それは猫かもしれません! あなたが達成しようとしているのは、dbからフェッチされた Dogタイプの別のオブジェクトから、タイプのオブジェクトを作成することだと思います。Animal

Animal1 つの方法は、Dogのオーバーロードされたコンストラクター で型のオブジェクトを受け入れることです。

class Dog:Animal
{
    public Dog(Animal animal)
    {
        this.Id = animal.Id;
       this.Name = animal.Name;
    }
...
}

このようにして、次のものを簡単に使用できます。

if ( some logic to determine that this animal is a dog )
{
    Dog d = new Dog(a);
    d.sniffBum();
}
于 2013-04-25T12:57:37.793 に答える
0

私はこのように動作しません。キャストは、インスタンスを特定の型として解釈する操作であり、その型は変更されません。あなたの場合、最初にその特定のデータベース行にある動物の種類を特定してから、正しい先祖をインスタンス化する必要があります。擬似コード:

var row = Fetch from database;
Animal animal;
if (row is a dog) animal = new Dog();
else if (row is a cat) animal = new Cat();
于 2013-04-25T12:49:05.790 に答える
0

オブジェクトにいくつかの静的メソッドを作成するか、パラメータとして渡して Dog を作成させるか、または返すことができるDog何らかの種類のメソッドを作成します。DogFactoryAnimalnull

その方法では、動物の特徴をチェックして、犬にするかどうかを確認できます(4本足、ビットなど)。

Animalそうでなければ、作成されたオブジェクトから具体的なDogオブジェクトに進むのは難しいでしょう

于 2013-04-25T12:58:27.880 に答える
0

あなたはこれを行うことができます:

var dog = a as Dog;
if(dog != null)
{
    dog.DoSomething();
}

後でキャストする必要がある場合は、 a が Dog かどうかを確認することをお勧めします。次の回答を参照してください: CLR でのキャストと 'as' キーワードの使用

于 2013-04-25T12:52:34.123 に答える