2017-12-29 40 views
1

私は基底クラスItemと、Itemを継承する子クラスBallを持っています。C#多態性コンストラクタ

public class Item 
{ 
    public string Name { get; set; } 
    public uint ID { get; set; } 

    public Item(ItemData data) 
    { 
     Name = data.Name; 
     ID = data.ID; 
    } 
} 

public class Ball : Item 
{ 
    public float Radius { get; set; } 

    public Ball(BallData data) : base(data) 
    { 
     CatchRate = data.Radius; 
    } 
} 

彼らは、コンストラクタがItemDataまたはBallDataオブジェクトを取り込んでいます。 ItemDataからわずかのようなBallItemBallData継承:今

public class ItemData 
{ 
    public string Name { get; set; } 
    public uint ID { get; set; } 
} 

public class BallData : ItemData 
{ 
    public float Radius { get; set; } 
} 

は、私がItemDataオブジェクトitemDataObjを持っています。これがBallDataオブジェクト(XMLファイルから直列化解除されたもの)でもあるかどうかはわかりません。

new Item(itemDataObj) 

は基本的に、私は私のコンストラクタがチェーンを形成したい:私は何をしたいだけItemDataオブジェクトであるItemitemDataObj場合itemDataObjBallDataオブジェクトである場合は、次のコードは、Ballオブジェクトを作成しており、作成され(多形性)のものであり、適切なものがItemDataのそれぞれのタイプに対して選択される。

+4

コンストラクタは多型ではありません。特定のシリアライズライブラリ/フレームワークやファクトリリーダーメソッドによって提供される "デシリアライゼーション"コードは、*正しい*コンストラクタを呼び出す責任があります。 – user2864740

+0

@ user2864740ああ、ありがとう。それはあまりにも悪いです。 – BlueberryKing

+1

多形のコンストラクタは意味をなさない。これは、オブジェクトの具体的な型を知る必要があるときです。この場合、 'new ball'を作成します。ボールコンストラクターは基本クラスコンストラクターを呼び出すか、ボールアイテムを – zzxyz

答えて

1

私は実際にGetItem()メソッドを実装することで、この特定のケースのための解決策を見つけることができた:私は行うことができます

public class ItemData 
{ 
    public string Name { get; set; } 
    public uint ID { get; set; } 

    public virtual Item GetItem() 
    { 
     return new Item(this); 
    } 
} 

public class BallData : ItemData 
{ 
    public float Radius { get; set; } 

    public override Item GetItem() 
    { 
     return new Ball(this); 
    } 
} 

この方法:

itemDataObj.GetItem(); 

が私のItemまたはBallがそれぞれ取得するために。

+0

**動的バインディング**を使用することは、そのような使用例には最適です。同様の手法が[visitor-visited](https://sourcemaking.com/design_patterns/visitor)デザインパターンにも使用されています。 – Ori