8

次のような基本クラスと派生クラスがあります

public class animal
{
    public string name { get; set; }
}

public class dog : animal
{
    public int age { get; set; }
    public string type { get; set; }
}

用途:

animal a = new animal();

dog d = new dog();

a = d; //compiled

d = a; //Error:Cannot implicitly convert type 'animal' to 'dog'.

d = (dog)a; // compiled

派生クラスを base に割り当てることができるが、逆の明示的な変換を行う必要がある内部的にはどうなりますか? 基本クラスと派生クラスの両方に同じメンバーが含まれていても、同じ結果が見つかりました。

4

5 に答える 5

9

すべての犬は動物ですが、すべての動物が犬というわけではありません。a が実際には d ではない可能性があるため、暗黙的な変換は許可されません。

于 2011-12-16T03:09:50.253 に答える
6

あなたの場合、明示的な変換を使用すると、何が起こっているのかを知っていることをコンパイラに伝えています。コードをコンパイルして を削除しd = a;、 のパブリック メンバーにアクセスしようとするとd、例外がスローされます。これは、この例ではanimalが ではないためdogです。を明示的に作成し、animalに割り当てましたa

明示的な変換を使用すると、変換が機能することがわかっている場合に実行できます。

public class MyClass
{
    public animal MyAnimal { get; private set; }

    public MyClass ()
    {
        MyAnimal = new dog ();
    }

    public void SetAge (int Age)
    {
        ((dog)MyAnimal).age = Age;
    }
}

MyAnimalこの場合、が実際にはであることがわかっているdogので、明示的なキャストを行うことができます。これらはすべて継承によって機能します。継承は両方の方法で機能しないため、コンパイラは暗黙的なアップ キャストを許可しません。明示的に行う必要があります。

クラスがその基本クラスから継承する場合、パブリック プロパティとメソッドを取得することがわかっています。animalへの参照に常に のプロパティとメソッドが含まれるとは言えませんdog

于 2011-12-16T03:18:08.853 に答える
3

継承キャストの単純なルールです。例:犬は動物ですが、逆は真ではありません - Animal is Dog. 動物のサブクラスがいくつかあるかもしれません。

class Animal {}
class Dog : Animal {}
class Cat : Animal {}

Animal a=new Cat(); // OK
a=new Dog(); // OK

Cat c=a; //Invalid - var a might contains reference of Cat or Dog
Cat d=(Cat)a; // Throws InvalidCastException exception because "a" has ref. of Dog

したがって、スーパークラスの参照変数は、キャストなしでサブクラスのオブジェクトの参照を保持できますが、スーパークラスの参照変数からサブクラスの参照変数に参照を割り当てる場合は、キャストする必要があります。

MSDN の記事 - How to: Safely Cast by Using as and is Operators (C# Programming Guide) をご覧ください。

于 2011-12-16T03:11:58.480 に答える
2

派生クラスを base に割り当てることができるが、逆の明示的な変換を行う必要がある内部的にはどうなりますか? 基本クラスと派生クラスの両方に同じメンバーが含まれていても、同じ結果が見つかりました。

どちらの場合も、内部ではほとんど何も起きていません。オブジェクトは変更またはコピーされていません。むしろ、それへの参照が別の型の新しい変数に格納されているだけです。

変数がオブジェクトへの参照を保持できる場合、オブジェクトは aまたは aまたはその他である必要があり、変数もそれへの参照を保持できるため、 からdogへの暗黙的な変換animalが許可されます。dogdogpoodleanimal

対照的に、オブジェクトが実際には ではない可能性があるため、からanimalへの明示的な変換が必要です。この場合、ランタイム システムは例外を発生させます。(「内部でほとんど何も起きていない」と言ったのを覚えていますか?ランタイム システムは、オブジェクトが であることを確認し、それ以外の場合は例外を発生させる必要があるため、「ほとんど何も起きていません」。)doganimaldogdog

dog d = a;これは言語設計上の決定です —と同等であることを除いて、C# とまったく同じ言語を確実に作成できますが、C# (および多くの同様の言語) の設計者は、実行時例外を時々発生させるdog d = (dog) a;と混乱するだろうと感じました。dog d = a;. a明示的なキャストにより、 a を参照しない限り例外が発生する可能性があることが明確になりdogます。

于 2011-12-16T03:23:33.760 に答える
2

すべての犬はすでに動物ですが、すべての動物が犬であるとは限りません。動物を犬に割り当てるには、まずそれを犬に変換する必要があります。

于 2011-12-16T03:09:39.243 に答える