字典和子类

本文关键字:子类 字典 | 更新日期: 2023-09-27 18:00:02

我正试图弄清楚某些事情是否可能。

我有一本字典

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

Class值实际上是一个具有多个子类的Parent类。

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

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

有人有办法做到这一点吗,或者他们有其他建议做这样的事情吗?

字典和子类

生成任何类型的字典时,都会强制泛型在键中为ushort,在值中为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 { }

您需要的是一个工厂来创建基于某种标识符的子类

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

一个奇怪的请求,已经解决。我不确定你是否清楚你的要求。

我正在添加我的版本。我将它创建为一个测试单元,但您可以将代码复制/粘贴到其他地方。

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