I am experiencing some issues in creating a nested object structure in C# using Dictionaries & Generics (I am using Visual Studio, .NET Framework 4.6+)
The main problem is the absence of covariance in C# Dictionaries.
I have to create this simple (JSON serializable/deserializable) object structure in C#. I try to explain using the animals...
public class AnimalCatalog
{
public Dictionary<string, Animal> AnimalsDict { get; set; } // key is the species name
}
public class Animal // base class
{
public string Species { get; set; } // univocal
public bool CanFly { get; set; }
public Dictionary<string, GenericPaw> PawsDict { get; set; } // each animal has a different type and a different number of paws
}
public class GenericPaw // base class
{
public int FingerNumber { get; set; } // number of finger in each paw
}
public class Cat : Animal // derived class
{
public void meow() // only cats says 'meow'
{...}
}
public class CatPaw : GenericPaw // derived class
{
public void scratch() // cats paws could scratch something :) but not all the animals paws could
{...}
}
I implemented this structure using C# generics, because a Cat has a dictionary of CatPaws, not generic Paws :P. this is my proposal.
public class AnimalCatalog<T,V> where T : Animal<V> where V : GenericPaw
{
public Dictionary<string, T> AnimalsDict { get; set; } = new Dictionary<string, T>(); // key is the species name
}
public class Animal<T> where T : GenericPaw // base class
{
public string Species { get; set; } // univocal
public bool CanFly { get; set; }
public Dictionary<string, T> PawsDict { get; set; } // each animal has a different type and a different number of paws
}
public class GenericPaw // base class
{
public string PawName { get; set; } // univocal
public int FingerNumber { get; set; } // number of finger in each paw
}
public class Cat<T> : Animal<T> where T : CatPaw // derived class
{
public void meow() // only cats says 'meow'
{...}
}
public class CatPaw : GenericPaw // derived class
{
public void scratch() // cats paws could scratch something :) but not all the animals paws could
{...}
}
let's use the created class
Cat<CatPaw> Kitty = new Cat<CatPaw>(); // create a cat
CatPaw KittyFirstPaw = new CatPaw(); // create the 1st cat's paw
Kitty.PawsDict.Add(KittyFirstPaw.PawName, KittyFirstPaw); // add the paw to the dict
AnimalCatalog<Animal<GenericPaw>,GenericPaw> ZooCatalog = new AnimalCatalog<Animal<GenericPaw>,GenericPaw>(); // create a catalog of animals
Animal<GenericPaw> GenericAnimal = Kitty; <-- doens't compile (can't convert derived to base class)
AnimalCatalog.AnimalsDict.Add(GenericAnimal.Species, GenericAnimal);
I also tried using an interface instead of a base class, using the out keyword to specify T as a covariant type, but it doesn't work because I can't use a covariant type in a dict...
Any help is very appreciated :) Stefano