2017-12-29 60 views
1

Ich habe eine Basisklasse Item und eine Kindklasse Ball, die von Item erbt.C# Polymorpher Konstruktor

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; 
    } 
} 

Sie sind Konstruktor in einem ItemData oder einem BallData Objekt. Genau wie Ball und Item, BallData erbt von ItemData:

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

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

Nun, ich habe ein ItemData Objekt itemDataObj. Beachten Sie, dass ich nicht weiß, ob dies auch ein BallData Objekt ist (deserialisiert von und XML-Datei). Was ich will, ist, tun Sie den folgenden Code ein Ball Objekt erstellen, wenn itemDataObj auch ein BallData Objekt ist, und erstellen Sie ein Item wenn itemDataObj ist nur ein ItemData Objekt:

new Item(itemDataObj) 

Grundsätzlich möchte ich meine Konstrukteure eine Kette bilden of responsibily (polymorph), wobei für den jeweiligen Typ ItemData der passende ausgewählt wird.

+4

Konstruktoren sind * nicht * polymorph. Der "Deserialization" -Code (z. B. von einer spezifischen Serialisierungsbibliothek/Framework- oder Factory-Reader-Methode bereitgestellt) ist für den Aufruf des * correct * -Konstruktors verantwortlich. – user2864740

+0

@ user2864740 Ah, danke. Das ist sehr schade. – BlueberryKing

+1

Ein polymorpher Konstruktor macht keinen Sinn. Es ist das eine Mal, dass Sie den konkreten Typ des Objekts kennen müssen. In diesem Fall erstellen Sie einen 'neuen Ball'. Der Ballkonstruktor kann alle notwendigen Entscheidungen treffen, einschließlich, ob der Basisklassenkonstruktor aufgerufen wird oder ein BallItem – zzxyz

Antwort

1

ich es tatsächlich geschafft, eine Lösung für diesen speziellen Fall zu finden, indem eine GetItem() Verfahren implementiert:

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); 
    } 
} 

Auf diese Weise kann ich tun:

itemDataObj.GetItem(); 

meiner Item oder Ball jeweils zu erhalten.

+0

Die ** dynamische Bindung ** eignet sich hervorragend für solche Anwendungsfälle. Eine ähnliche Technik wird für das Entwurfsmuster [Besucher besucht] (https://sourcemaking.com/design_patterns/visitor) verwendet. – Ori