6
public class Derived : BaseClass
{
    public Derived(string name) : base(name) {}

    public static implicit operator BaseClass(Derived derived)
    {
        return new BaseClass(derived.ColorHex);
    }

    public static implicit operator Derived(BaseClass baseclass)
    {
        return new Derived(baseclass.name);
    }
}

これはうまくいきません。なぜ許可されないのですか?特にベースから派生したものに変換するときに、意味をなすために必要なロジックを書くことができる可能性があり
ます

編集:質問のタイトルを変更しました

4

5 に答える 5

9

Derivedからへの暗黙的な変換がすでに存在するためBaseClass、その逆は意味をなさないからです。

後者に関して:Baseオブジェクトが暗黙的に変換可能であることを意図している場合、そもそもオブジェクトでDerivedはないのはなぜですか?Derived

標準からの必須の引用:

6.1.6 暗黙の参照変換

暗黙の参照変換は次のとおりです。

  • [...]
  • S が T から派生している場合、任意のクラス型 S から任意のクラス型 T へ。

これは、誰もが知っているように、暗黙的な変換Derived=>があることを示しBaseています。

6.2.4 明示的な参照変換

明示的な参照変換は次のとおりです。

  • [...]
  • S が T の基本クラスである場合、任意のクラス型 S から任意のクラス型 T へ。
  • [...]

これは、明示的な変換Base=>が既に存在Derivedすることを示しています (これにより、実行時にダウンキャストを試すことができます)。

6.4.1 許可されているユーザー定義の変換

C# では、特定のユーザー定義の変換のみを宣言できます。特に、既存の暗黙的または明示的な変換を再定義することはできません。

これは、対象の 2 つの変換が言語によって既に定義されているため、再定義できないことを示しています。

于 2012-06-01T15:29:14.293 に答える
1

それはポリモーフィズムのシマニクスを乱すからです。

于 2012-06-01T15:29:43.763 に答える
1

オブジェクトを独自の型にキャストした結果が元のオブジェクトであるという一般的な規則があります。型の格納場所がBaseTypeのインスタンスを保持している場合DerivedType、元の型から へのキャストは、DerivedType使用するようにコンパイラに指示する必要があります。DerivedTypeのメンバーですが、実際にはオブジェクトに対して何も「実行」してはなりません。カスタムのベースから派生への変換演算子が許可されている場合は、次のいずれかが必要になります。(1) インスタンスへのキャストの独自の型操作で新しいオブジェクトが生成される場合と生成されない場合がある、または (2) 派生型を持つ基本型の格納場所に格納されているオブジェクトは、基本型または関連のない型のオブジェクトとは大幅に異なる動作をしますが、そうするようにする明確に目に見える型チェック コードはありません。基本型パラメーターを指定すると、新しい派生型オブジェクトを返すメソッドが必要になる場合がありますが、派生型のインスタンスが指定された場合は、単にそれを変更せずに返すことをお勧めしますが、一般的には、型キャストではなく、メソッドのように「見える」ようにします。

ところで、コンパイラが上記のあいまいさなしに「基本型」と「派生型」の間でユーザー定義の型変換を許可できる状況が 1 つあります。型の 1 つが構造体の場合です。C# は値型が から継承されているように見せかけていますがValueType、すべての値型定義は実際には 2 つのものを定義しています: から派生したヒープ オブジェクト型ValueType、およびオブジェクトではなく、何からも派生しないストレージの場所のコレクションです。C# では、後者の型から前者への暗黙的なキャスト演算子と、前者から後者への明示的なキャスト演算子が定義されています。ヒープ オブジェクトと格納場所のコレクションとの間の変換は参照保持ではないため、ユーザー定義の変換演算子をそのようなコンテキストで使用できるようにしても、継承のセマンティクスが混乱することはありません。このような変換の唯一の問題は、それらを使用する値型がジェネリック型として使用できないか、ジェネリック型として渡された場合に特別な動作を失うという事実です。

于 2012-06-01T17:38:34.367 に答える
0

合成するには、コードを記述せずに Derived オブジェクトを BaseClass オブジェクトにキャストできます。

BaseClass baseClass = new BaseClass("");
Derived derived = new Derived("");

baseClass = (BaseClass)derived;

ただし、Derived から BaseClass へのキャストを書き換えることはできません。

BaseClass から Derived への他のキャストについては、あまり意味がありません。

結論として、2 つのクラス間に継承関係がない場合にのみ、キャストを再定義できます。

于 2012-06-01T15:39:09.973 に答える