Reputation: 77
I am trying to figure out if something is even possible.
I have a dictionary
Dictionary<ushort,ParentClass> ClassList = new Dictionary<ushort,ParentClass>
The Class value is actually a Parent class with multiple sub-classes.
When adding to the dictionary I want to add/create a sub-class rather than the parent, that will vary based on each add, IE, a different (potentially) sub-class each add. I should add I want this to be dynamic, meaning some property of the function will indicate which sub-class to add.
public void addClass(ushort ID,ushort SomeSubClass)
{
ClassList.Add(ID,SomeSubClass);
}
Does anybody have a way to do this, or do they have another recommendation for doing something like this?
Upvotes: 0
Views: 774
Reputation: 485
A strange request, already resolved. I am not sure you are clear on what you asked.
I am adding my version. I created it as a test unit but you can copy/paste the code somewhere else.
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);
}
}
}
Upvotes: 0
Reputation: 544
When you generate any kind of dictionary you're forcing the generics to be a ushort in the key and ParentClass in the value. Which means that, once you add any subclass instance to the dictionary and you're retrieving this instance from the dictionary again, you will get it upcasted to ParentClass.
Knowing that, you want to check upon retrieval if it's any kind of subclass. In most cases with proper abstractions or interface this is not necessary - so you might have an issue on your underlying architecture.
Here is an example with 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 { }
Upvotes: 2
Reputation: 5735
What you need is a factory to create the sub class based on some sort of identifier
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();
}
}
}
and sub type should be defined like so :
class SubType1 : ParentClass
{
}
Upvotes: 0