2016-08-03 24 views
0

我想弄清楚是否有可能。字典和子類

我有一本字典

Dictionary<ushort,ParentClass> ClassList = new Dictionary<ushort,ParentClass> 

的Class值實際上是一個父類多個子類。

當添加到字典中時,我想添加/創建一個子類而不是父級,這將根據每個添加,IE,不同的(可能)子類每個添加而變化。我應該添加我想這是動態的,這意味着函數的某些屬性將指示要添加哪個子類。

public void addClass(ushort ID,ushort SomeSubClass) 
{ 
    ClassList.Add(ID,SomeSubClass); 
} 

有沒有人有辦法做到這一點,還是他們有另一個建議做這樣的事情?

+0

dictionary接受'ParentClass'類型的值。那麼你如何儲存'ushort'? – Rahul

+1

您可能需要考慮使用工廠方法模式(https://en.wikipedia.org/wiki/Factory_method_pattern)。 –

+0

更多的佔位符。 IE如果somesubclass = 1,然後添加subclass1等。 – Angryjames

回答

0

你需要的是一個工廠基於某種​​標識的

public void addClass(ushort ID,ushort someSubClassType) 
{ 
    ClassList.Add(ID,ClassFactory.Create(someSubClassType)); 
} 

static class ClassFactory 
{ 
    static ParentClass Create(ushort type) 
    { 
      // Create specific sub type base on type 
      if (type == 1) 
      { 
       return new SubType1(); 
      } 
    } 
} 

和子類型應該像這樣被定義爲創建子類:

class SubType1 : ParentClass 
{ 
} 
+0

這可能會起作用,我會試一試。 – Angryjames

2

當你產生任何形式的字典你迫使泛型成爲鍵中的一個祕訣,值中的ParentClass。這意味着,一旦將任何子類實例添加到字典中,並且您再次從字典中檢索此實例,則會將其升級爲ParentClass。

知道了,如果它是任何類型的子類,你都要檢查檢索。在大多數情況下,如果有適當的抽象或接口,這不是必需的 - 因此您的基礎架構可能存在問題。

這裏是用C#互動的示例:

> class Animal { } 
> class Dog : Animal { } 
> Dictionary<ushort, Animal> dict = new Dictionary<ushort, Animal>(); 
> dict.Add((ushort) 1, new Dog()); 
> dict.ElementAt(0) 
KeyValuePair<ushort, Submission#0.Animal> { 1, Submission#1.Dog { } } 
> var animalInstanceForSure = dict.ElementAt(0).Value; 
> animalInstanceForSure 
Submission#1.Dog { } 
0

的奇怪要求,已經解決了。我不確定你清楚你的問題。

我正在添加我的版本。我將它創建爲測試單元,但您可以將代碼複製/粘貼到其他位置。

using System; 
using Microsoft.VisualStudio.TestTools.UnitTesting; 
using System.Collections.Generic; 

namespace Utilities_Tests 
{ 

    public class ParentClass 
    { 
     public List<ParentClass> Children { get; set; } 

     public string Name { get; set; } 

     public virtual char Sex { get; private set; } 

     public virtual bool IAmTheUniqueGrandPapa { get { return true; } } 

     public ParentClass BringToLife(int atype) 
     { 
      ParentClass newItem = this; 

      switch (atype) 
      { 
       case 1: newItem = new MaleChild() { Name = $"I am a child of {Name}" }; break; 
       case 2: newItem = new FemaleChild() { Name = $"I am a child of {Name}" }; break; 
       case 3: newItem = new OtherChild() { Name = $"I am a child of {Name}" }; break; 
      } 

      Children.Add(newItem); 
      return newItem; 
     } 

     public ParentClass(char sex = 'F') 
     { 
      Children = new List<ParentClass>(); 
      Sex = sex; 
     } 
    } 


    public class MaleChild : ParentClass 
    { 
     public override bool IAmTheUniqueGrandPapa { get { return false; } } 
     public override char Sex { get { return 'M'; } } 
    } 

    public class FemaleChild : ParentClass 
    { 
     public override bool IAmTheUniqueGrandPapa { get { return false; } } 
     public override char Sex { get { return 'F'; } } 
    } 

    public class OtherChild : ParentClass 
    { 
     public override bool IAmTheUniqueGrandPapa { get { return false; } } 
     public override char Sex { get { return '?'; } } 
    } 


    public class NewDictionary<K, V> : Dictionary<K, V> where V : ParentClass 
    { 
     public void AddOne(K key, V fromWhom, int atype) 
     { 
      this[key] = (V)fromWhom.BringToLife(atype); 
     } 
    } 


    [TestClass] 
    public class AStrangeRequest 
    { 
     [TestMethod] 
     public void AStrangeTest() 
     { 
      var dict = new NewDictionary<uint, ParentClass>(); 

      var aParent = new ParentClass(); 

      dict.AddOne(00, aParent, 0); // F parent 
      dict.AddOne(11, aParent, 1); // M 
      dict.AddOne(22, aParent, 2); // F 
      dict.AddOne(33, aParent, 3); // ?    

      Assert.IsTrue(dict[0].IAmTheUniqueGrandPapa == true && dict[0].Sex == 'F'); 
      Assert.IsTrue(dict[0].Children.Count > 0); 

      Assert.IsTrue(dict[11].IAmTheUniqueGrandPapa == false && dict[11].Sex == 'M'); 
      Assert.IsTrue(dict[11].Children.Count == 0); 

      Assert.IsTrue(dict[22].IAmTheUniqueGrandPapa == false && dict[22].Sex == 'F'); 
      Assert.IsTrue(dict[22].Children.Count == 0); 

      Assert.IsTrue(dict[33].IAmTheUniqueGrandPapa == false && dict[33].Sex == '?'); 
      Assert.IsTrue(dict[33].Children.Count == 0); 
     } 
    } 
}