2011-12-13 7 views
3

オブジェクトをベースから派生オブジェクトにキャストすることは可能ですか?たとえば、基本オブジェクトが1つあるとします:Animal。これから私は他のクラスのいくつかを派生させました:CatDog。 今私はAnimalが必要ですが、現時点でのタイプは本当に重要ではありません。だから、道に沿ってベースからのキャスティングは派生しましたか?

Animal blankCanvas = new Animal(); 

は、私は私の心を変え、今DogにそのAnimalを変更したいです。しかし、私はそれをどうやってやるのか分かりません。私はAnimalからDogに変換するビジネスルールを知っていますが、私はその実装方法を知らないだけです。

+1

これを試してみるとどうなりますか? AnimalとDogの2つのクラスを持つコンソールアプリケーションを作成します。あなたが使用されているものがはっきりと分かるように、それらを十分に異なるものにして、キャストしてみてください。エラーが発生した場合は、投稿してください。 – taylonr

答えて

1

カスタム変換を書き込むことなくこれを行う方法はありません。おそらく、あなたが必要とするどのような種類の派生型をより早く決定し、そのインスタンスを作成するのがより良いことです。

ほとんどの場合、タイプシステムがこの方法であなたと戦うことになるときには、アーキテクチャを再設計する必要があります。

+1

-1ベースから派生型へのカスタム変換は記述できません。つまり、これはコンパイルされません:class Derived:Base {public static explicit operator Derived(Base b){return new Derived(); }} 'エラーは、"基本クラスとの間でのユーザー定義の変換は許可されていません "。 – phoog

+0

@phoog:これは、カスタムコンバージョンを表現する単なる1つの方法です。完全に合法であるそれをする他の多くの方法があります。 –

+0

あなたの答えを編集しない限り、私はダウン投票を削除できません。もしあなたがそうすれば、私はそうするでしょう。オブジェクトのタイプと参照のタイプとの間の区別を維持するために、+1, – phoog

3

はい、派生リファレンスへのベース参照をキャストできます。

しかし、インスタンスを変換したいようです。それは鋳造ではなく、直接的に可能ではありません。

ロジックは、作成する時点でどのようなタイプが必要なのかを知っている必要があります。以下は意味作ることができる

:正しいパスを保つためにあなたを助けるために

Animal blankCanvas = null; 
... 
blankCanvas = new Dog(); 

を、すべての後abstract class
として動物を定義し、Animalのインスタンスが何を表すのでしょうか?

Public Dog(Animal pAnimal) 
{ 
    //do stuff... 
} 
+0

+1である。それを強調するために、参照が派生型である(または由来する)オブジェクトへの参照を指していない限り、派生参照への基本参照のキャストは失敗します。 – phoog

0

一度「動物として生まれた」の生命はAnimalとして生きるでしょう。派生クラスにキャストしようとすることはできますが、インスタンス自体はAnimalのままなので、すべてのケースで失敗します。ここで

は、あなたが他のクラスにそれを変更することができますどのようにいくつかの提案は以下のとおりです。

あなたは静的メソッドを使用して明示的に実装することにより、別のクラスにカスタム変換を実装することができ、例えば、あなたが何かを実装することができます

public class Cat : Animal 
{ 
public Cat FromAnimal(Animal animal) 
{ 
    return new Cat(animal) {Eyes = Color.Blue, ... }; 
} 
} 

別のクラスでデシリアライズをサポートする特定のシリアライザを使用して、インスタンスをシリアライズしてからデシリアライズできます。

明示的な戻り型の派生型を使用してインスタンスのディープ・クローニングを実装できます。

次に、古いAnimalをnew-bord Catに置き換えて、どこでも使用できます。

/// <summary> 
/// Dog. 
/// </summary> 
class Dog : Animal 
{ 
    /// <summary> 
    /// Initializes a new instance of the <see cref="Dog"/> class. 
    /// </summary> 
    /// <param name="type">The type.</param> 
    public Dog(string type) 
     : base(type) 
    { } 

    /// <summary> 
    /// Gets a dog from an animal. 
    /// </summary> 
    /// <param name="animal">The animal.</param> 
    /// <returns></returns> 
    public static Dog FromAnimal(Animal animal) 
    { 
     return new Dog(animal.Type); 
    } 
} 

/// <summary> 
/// Animal. 
/// </summary> 
class Animal 
{ 
    /// <summary> 
    /// Gets or sets the type. 
    /// </summary> 
    /// <value>The type.</value> 
    public string Type { get; private set; } 

    /// <summary> 
    /// Initializes a new instance of the <see cref="Animal"/> class. 
    /// </summary> 
    /// <param name="type">The type.</param> 
    public Animal(string type) 
    { 
     this.Type = type; 
    } 
} 

するか、あなたが必要とするすべての変換を管理するために、単一のファクトリクラスを使用します。

0

クラスのインスタンス:私の知る限り、あなたがキャストであることを行うことはできません知っているが、あなたは、このようなパラメータとして受け入れ、動物しまう犬でコンストラクタを持つことができますよう

+0

"特定のコンテキストで派生クラスにキャストしようとすることができます" ...しかし、そのキャストは常に失敗*します。 – phoog

+0

@phoog:はい、私はそれを明確にしませんでした、申し訳ありません、私は答えを編集します! –

2

次のような派生クラスの静的メソッドを使用することができます。

関連する問題