字典和子类

时间:2016-08-03 21:44:38

标签: c# dictionary

我想弄清楚是否有可能。

我有一本字典

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

Class值实际上是一个包含多个子类的Parent类。

当添加到字典时,我想添加/创建一个子类而不是父类,这将根据每个添加,IE,每个添加的不同(可能)子类而有所不同。我应该添加我希望它是动态的,这意味着函数的某些属性将指示要添加的子类。

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

有人有办法做到这一点,还是他们有另外的建议来做这样的事情?

3 个答案:

答案 0 :(得分:2)

当您生成任何类型的字典时,您强制将泛型作为键中的ushort和值中的ParentClass。这意味着,一旦你将任何子类实例添加到字典中并且你再次从字典中检索这个实例,你就会将它上传到ParentClass。

知道这一点,你想要检查它是否是任何类型的子类。在大多数情况下,通过适当的抽象或接口,这不是必需的 - 因此您的基础架构可能存在问题。

以下是C#Interactive的示例:

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

答案 1 :(得分: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 
{
}

答案 2 :(得分: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);
        }
    }
}