I need the following inheritance:
public class Persistent
{
public virtual Persistent Clone() { ... }
}
public class Animal : Persistent
{
public override Animal Clone() { ... }
}
This can be implemented using a generic class:
public class Persistent<T>
{
public virtual T Clone() { ... }
}
public class Animal : Persistent<Animal>
{
public override Animal Clone() { ... }
}
However inheriting further from Animal does not work:
public class Pet : Animal
{
public override Pet Clone() // return type is Animal
}
Obviously Pet should derive from Persistent<Pet> for this to work but I need classic inheritance. Unfortunately C# supports neither multiple inheritance nor mixins. Is there any workaround?
This works the way you want it to, although I'd ask why Persistent needs to be a class and not an interface.
public class Persistent
{
public virtual Persistent Clone() { return null; }
}
public class Animal : Persistent<Animal>
{
public override Animal Clone() { return null; }
}
public class Persistent<T>
{
public virtual T Clone() { return default(T); }
}
public class Animal : Persistent<Animal>
{
public override Animal Clone() { return null; }
}
public class Pet : Animal
{
public new Pet Clone()
{
return null;
}
}
Here is a simple solution with generics:
public abstract class Persistent<T>
{
protected abstract T CloneOverride();
public T Clone()
{
return CloneOverride();
}
}
public class Animal : Persistent<Animal>
{
protected override Animal CloneOverride()
{
return new Animal();
}
public new Animal Clone()
{
return CloneOverride();
}
}
public class Pet : Persistent<Pet>
{
protected override Pet CloneOverride()
{
return new Pet();
}
public new Pet Clone()
{
return CloneOverride();
}
}
(see also my other answer without generics)
Here is a simple solution without generics:
public class Persistent
{
protected virtual object CloneOverride()
{
return new Persistent();
}
public Persistent Clone()
{
return (Persistent)CloneOverride();
}
}
public class Animal : Persistent
{
protected override object CloneOverride()
{
return new Animal();
}
public new Animal Clone()
{
return (Animal)CloneOverride();
}
}
public class Pet : Animal
{
protected override object CloneOverride()
{
return new Pet();
}
public new Pet Clone()
{
return (Pet)CloneOverride();
}
}
The good point is that you hide ancestors Clone() methods as expected, and the pattern is always the same.
The drawback is that it's easy to make a mistake because CloneOverride() is not type safe.
(see also my other answer with generics)
With method hiding
public class Persistent
{
public Persistent Clone() { ... }
}
public class Animal : Persistent
{
public new Animal Clone() { ... }
}
From your code I am assuming you are doing it for cloning. So you can create a cloner,
public class Persistent
{
public virtual Dictionary<string, object> GetCloneDictionary()
{
return //dictionary containning clonning values.
}
public void SetValues( Dictionary<string, object> objects)
{
//set values from dictionary
}
}
public class Animal : Persistent
{
public override Dictionary<string, object> GetCloneDictionary()
{
return //dictionary containning clonning values.
}
public override void SetValues( Dictionary<string, object> objects)
{
}
}
public class Animal2 : Animal
{
public override Dictionary<string, object> GetCloneDictionary()
{
return //dictionary containning clonning values.
}
public override void SetValues( Dictionary<string, object> objects)
{
}
}
public class PersistentClonner<T> where T : Persistent
{
public virtual T Clone(T obj)
{
obj.GetCloneDictionary();
//create new and set values
return //new clone
}
}
public class AnimalClonner : PersistentClonner<Animal>
{
public override Animal Clone(Animal obj)
{
obj.GetCloneDictionary();
//create new and set values
return //new clone
}
}
Will this help?
public class Persistent
{
public virtual Persistent Clone()
{
return new Persistent();
}
}
public class Animal : Persistent
{
public new Animal Clone()
{
return new Animal();
}
}
public class Pet : Animal
{
}
public class Wild : Animal
{
public new Wild Clone()
{
return new Wild();
}
}
private static void Test()
{
var p = new Persistent().Clone();
Console.WriteLine("Type of p: {0}", p);
var a = new Animal().Clone();
Console.WriteLine("Type of a: {0}", a);
var t = new Pet().Clone();
Console.WriteLine("Type of t: {0}", t);
var w = new Wild().Clone();
Console.WriteLine("Type of w: {0}", w);
}
Related
I am trying to learn the factory design pattern. I have created a code for creating two animals (for now only dogs and a cats).
I have got an Animal (as a product)
public abstract class Animal
{
public abstract void CreateBody();
public abstract void CreateLeg();
}
Dog and Cat Implements Animal class:
public class Dog: Animal
{
public override void CreateBody()
{
Console.WriteLine("Dog body created");
}
public override void CreateLeg()
{
Console.WriteLine("Dog body created");
}
}
Cat Implements Animal:
public class Cat: Animal
{
public override void CreateBody()
{
Console.WriteLine("Cat body created");
}
public override void CreateLeg()
{
Console.WriteLine("Cat Leg created");
}
}
Created a factory class that makes different animal according to the input given in the parameter:
public class AnimalFactory
{
public static Animal CreateAnimal(string animal)
{
Animal animalDetails = null;
if (animal == "cat")
{
animalDetails = new Cat();
}
else if (animal == "dog")
{
animalDetails = new Dog();
}
animalDetails.CreateBody();
animalDetails.CreateLeg();
return animalDetails;
}
}
In the main it is used as:
static void Main(string[] args)
{
Animal animalDetails = AnimalFactory.CreateAnimal("cat");
if (animalDetails != null)
{
}
else
{
Console.Write("Invalid Card Type");
}
Console.ReadLine();
}
Here in this code, I know exactly what methods I need to call to create an animal, so I called those methods in the factory class.
As I read in the various tutorials and books, most of the implementation of the factory method uses another concrete factory method to create the concrete product?
In what case it is appropriate to create the concrete factory method? Is that concrete factory relevant in this demo too?
My implementation :
Animal interface :
public interface IAnimal
{
void CreateBody();
void CreateLeg();
}
Cat & Dog classes:
public class Dog : IAnimal
{
public void CreateBody()
{
Console.WriteLine("Dog body created");
}
public void CreateLeg()
{
Console.WriteLine("Dog leg created");
}
}
public class Cat : IAnimal
{
public void CreateBody()
{
Console.WriteLine("Cat body created");
}
public void CreateLeg()
{
Console.WriteLine("Cat leg created");
}
}
Animal factory
public static class AnimalFactory
{
public static IAnimal? GetInstance(Type type)
{
if(type.GetInterfaces().Contains(typeof(IAnimal))) // check if type implement IAnimal
{
return Activator.CreateInstance(type) as IAnimal;
}
return null;
}
}
Use case
IAnimal? cat = AnimalFactory.GetInstance(typeof(Cat));
IAnimal? dog = AnimalFactory.GetInstance(typeof(Dog));
cat?.CreateBody();
cat?.CreateLeg();
dog?.CreateBody();
dog?.CreateLeg();
this structure can be expanded into an abstractory factory provider. it currently demonstrate a simple factory provider model. The provider accepts the derived class of animal which is either cat or dog and sets a private label called type
public abstract class Animal
{
public string _Type;
public abstract void CreateBody();
public abstract void CreateLeg();
public abstract void SetType(string type);
}
public class Dog : Animal
{
public Dog() {
SetType("Dog");
}
public override void SetType(string type)
{
_Type = type;
}
public override void CreateBody()
{
Console.WriteLine("Dog body created");
}
public override void CreateLeg()
{
Console.WriteLine("Dog body created");
}
}
public class Cat : Animal
{
public Cat()
{
SetType("Cat");
}
public override void SetType(string type)
{
_Type = type;
}
public override void CreateBody()
{
Console.WriteLine("Cat body created");
}
public override void CreateLeg()
{
Console.WriteLine("Cat Leg created");
}
}
public class AnimalProviderFactory {
public AnimalProvider GetAnimalProvider()
{
return new AnimalProvider();
}
}
public class AnimalProvider{
public string GenerateShippingLabelFor(Animal catOrDog)
{
return catOrDog._Type;
}
}
public class AnimalType
{
private readonly Animal catOrDog;
private readonly AnimalProviderFactory animalProviderFactory;
public AnimalType(Animal catOrDog, AnimalProviderFactory animalProviderFactory)
{
this.catOrDog = catOrDog;
this.animalProviderFactory = animalProviderFactory;
}
public string Finalize()
{
var provider = animalProviderFactory.GetAnimalProvider();
return provider.GenerateShippingLabelFor(catOrDog);
}
}
public void TestAbstractFactory()
{
Cat cat = new Cat();
AnimalType animalType= new AnimalType(cat, new AnimalProviderFactory());
var type = animalType.Finalize();
_output.WriteLine(type);
Assert.True(true);
}
For all the entities in my project I have a base entity and from that interface another interface and then a class ( this is how it is and I cannot change it ).
Given any 2 objects, I want to call a method.
I have created a dictionary with a tuple key to be able to retrieve the right method.
This is the code:
public interface IAnimal
{
string Name { get; set; }
}
public interface IDog : IAnimal
{
}
public interface ICat : IAnimal
{
}
public interface IMouse : IAnimal
{
}
public class Cat : ICat
{
public string Name { get; set; }
}
public class Dog : IDog
{
public string Name { get; set; }
}
public class Mouse : IMouse
{
public string Name { get; set; }
}
public class Linker
{
private static Dictionary<Tuple<Type, Type>, object> _linkMethodsDictionary = new Dictionary<Tuple<Type, Type>, object>();
private static bool _linkDictionaryWasInitialized = false;
public void InitializeLinkMethods()
{
if (_linkDictionaryWasInitialized) return;
_linkMethodsDictionary.Add(Tuple.Create(typeof(IDog), typeof(ICat)), (Action<IDog, ICat>)LinkDogToCat);
_linkMethodsDictionary.Add(Tuple.Create(typeof(ICat), typeof(Mouse)), (Action<ICat, IMouse>)LinkCatToMouse);
_linkDictionaryWasInitialized = true;
}
public void Link<T, TU>(T entity1, TU entity2) where T : class, IAnimal
where TU : class, IAnimal
{
Action<T, TU> linkMethod = _linkMethodsDictionary[Tuple.Create(typeof(T), typeof(TU))] as Action<T, TU>;
if (linkMethod == null)
throw new NotImplementedException($"Could not find link method for {entity1.Name} and {entity2.Name}");
linkMethod(entity1, entity2);
}
public void LinkDogToCat(IDog dog, ICat cat)
{
Console.WriteLine($"Dog: {dog.Name} - Cat:{cat.Name}");
}
public void LinkCatToMouse(ICat cat, IMouse mouse)
{
Console.WriteLine($"Cat: {cat.Name} - Mouse:{mouse.Name}");
}
Not sure how to declare the key of the dictionary, because the call fails: "The given key was not present in the dictionary."
Linker linker = new Linker();
linker.InitializeLinkMethods();
ICat cat = new Cat() {Name = "The CAT"};
IDog dog = new Dog() {Name = "the DOG"};
IMouse mouse = new Mouse() {Name = "The MOUSE"};
linker.Link<ICat, IMouse>(cat, mouse);
linker.Link(dog, cat);
I have used a struct as a key for the Dictionary
internal struct EntityLinkKey
{
private readonly Type _first;
private readonly Type _second;
public EntityLinkKey(Type first, Type second)
{
this._first = first;
this._second = second;
}
public override int GetHashCode()
{
return this._first.GetHashCode() * 17 + this._second.GetHashCode();
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (GetType() != obj.GetType()) return false;
EntityLinkKey p = (EntityLinkKey)obj;
return p._first == this._first && p._second == this._second;
}
}
I'd like to implement abstract factory design pattern. I add this snippet :
public class Class1
{
static Ete _ete;
static Hiver _hiver;
public static void Main(Clothes cl)
{
_ete = cl.CreateEteClothes();
_hiver = cl.CreateHiverClothes();
Console.WriteLine(_ete.GetMarque());
Console.ReadKey();
Console.WriteLine(_hiver.GetMarque());
Console.ReadKey();
}
}
public abstract class Clothes
{
public abstract Ete CreateEteClothes();
public abstract Hiver CreateHiverClothes();
}
public abstract class ItalianFactory: Clothes
{
public override Ete CreateEteClothes()
{
return new TShirtJuve();
}
public override Hiver CreateHiverClothes()
{
return new PullJuve();
}
}
public abstract class FrenchFactory : Clothes
{
public override Ete CreateEteClothes()
{
return new TShirtPsg();
}
public override Hiver CreateHiverClothes()
{
return new PullPsg();
}
}
public abstract class TunisianFactory : Clothes
{
public override Ete CreateEteClothes()
{
return new TShirtCa();
}
public override Hiver CreateHiverClothes()
{
return new PullCa();
}
}
public abstract class Ete
{
public abstract string GetMarque();
}
public abstract class Hiver
{
public abstract string GetMarque();
}
public class TShirtJuve: Ete
{
public override string GetMarque()
{
return "Juventus T shirt";
}
}
public class TShirtPsg : Ete
{
public override string GetMarque()
{
return "PSG T shirt";
}
}
public class TShirtCa : Ete
{
public override string GetMarque()
{
return "club africain T shirt";
}
}
public class PullJuve : Hiver
{
public override string GetMarque()
{
return "Juventus Pull";
}
}
public class PullPsg : Hiver
{
public override string GetMarque()
{
return "PSg Pull";
}
}
public class PullCa : Hiver
{
public override string GetMarque()
{
return "Club africain Pull";
}
}
I'd like to test this implementation, but I get an exception indicates that the signature of main method is not acceptable.
So How can I fix my code to test this design pattern implementation?
You have public static void Main(Clothes cl)
This should be static void Main(string[] args) as this is the entry point for the application and there can be only one entry point. See the .NET documentation for more info.
A method's signature usually consists of the methods name, return type, and parameters. Your application is expecting the correct signature for the Main method, hence it's giving you this exception.
I'm trying to create an abstract generic class which inherits from another abstract generic class.
Here's what I have so far
public abstract class BaseClass {
public long Id { get; private set; }
public BaseClass(long id) {
this.Id = id;
}
}
public abstract class BaseClass<T> : BaseClass where T : BaseClass {
protected BaseClass(long id)
: base(id) {
}
public static T Get(long id) {
T item;
return TryGet(id, out item) ? item : default(T);
}
public static bool TryGet(long id, out T item) {
item = null; // This is where I call the cache but for this example I've removed so it will compile
if (item != null) { return true; }
else {
// Call TryGetFallback method
return false;
}
}
protected abstract T TryGetFallback(long id);
}
public abstract class DerivedClass : BaseClass<DerivedClass> {
public String Name { get; private set; }
public DerivedClass(long id, String name)
: base(id) {
this.Name = name;
}
}
public class DerivedDerivedClass : DerivedClass {
protected override DerivedDerivedClass TryGetFallback(long id) {
// Handle the try get fallback
}
}
The TryGetFallback method on the DerivedDerivedClass causes a compiler error.
First you need to fix your BaseClass<T> implementation to not have a recursive type constraint.
public abstract class BaseClass<T> : BaseClass where T : new() {
//snip
}
Then you can use it in your derived class, for example I will make it use int for the generic type parameter:
public abstract class DerivedClass : BaseClass<int> {
//snip
}
And now if you compile it will warn you that 'DerivedDerivedClass' does not implement inherited abstract member 'BaseClass<int>.TryGetFallback(long)'
Thanks for the tips #DavidG it's helped me to solve the problem with the following code
public abstract class BaseClass {
public long Id { get; private set; }
public BaseClass(long id) {
this.Id = id;
}
}
public abstract class BaseClass<T> : BaseClass where T : BaseClass<T>, new() {
protected BaseClass(long id) : base(id) { }
public static T Get(long id) {
T item;
return TryGet(id, out item) ? item : default(T);
}
public static bool TryGet(long id, out T item) {
item = null; // Try to get item from cache here
if (item != null) { return true; }
else {
T obj = new T();
item = obj.TryGetFallback(id);
return item != null;
}
}
protected abstract T TryGetFallback(long id);
}
public abstract class DerivedClass<T> : BaseClass<T> where T : DerivedClass<T>, new() {
public String Name { get; private set; }
public DerivedClass() : base(0) { }
public DerivedClass(long id, String name)
: base(id) {
this.Name = name;
}
protected abstract override T TryGetFallback(long id);
}
public class DerivedDerivedClass : DerivedClass<DerivedDerivedClass> {
public DerivedDerivedClass() {
}
protected override DerivedDerivedClass TryGetFallback(long id) {
throw new NotImplementedException();
}
}
I've this class structure:
namespace ClassLibrary1
{
public interface IComponentGuid { }
class ComponentGuid : IComponentGuid{}
internal interface IComponent<T> where T : IComponentGuid {
List<T> List();
}
class SpecificComponent : IComponent<ComponentGuid> {
public List<ComponentGuid> List()
{
throw new System.NotImplementedException();
}
}
class P
{
public P(IComponent<IComponentGuid> pComponent) { }
}
class Caller
{
public Caller()
{
var specific = new SpecificComponent();
var p = new P(specific);
}
}
}
The problem arise instantiating P: var p = new P(specific);
I get a
cannot convert from 'ClassLibrary1.SpecificComponent' to 'ClassLibrary1.IComponent<ClassLibrary1.IComponentGuid>'
What am I doing wrong?
Thank you.
You can make it work if you forgo List<T> on your interface and replace it with a co-variant interface of IEnumerable<T> and then make your type parameter co-variant as well:
namespace ClassLibrary1
{
public interface IComponentGuid { }
class ComponentGuid : IComponentGuid{}
internal interface IComponent<out T> where T : IComponentGuid {
IEnumerable<T> List();
}
class SpecificComponent : IComponent<ComponentGuid> {
public IEnumerable<ComponentGuid> List()
{
throw new System.NotImplementedException();
}
}
class P
{
public P(IComponent<IComponentGuid> pComponent) { }
}
class Caller
{
public Caller()
{
var specific = new SpecificComponent();
var p = new P(specific);
}
}
}
I'm trying this solution splitting the IComponent interface into two, one covariant and one invariant.
namespace ClassLibrary1
{
public interface IComponentGuid { }
public class ComponentGuid : IComponentGuid { }
public interface IComponentBase<out T> where T : IComponentGuid
{
IEnumerable<T> List();
}
interface IComponent<T>
{
void AddToList(T item );
}
public class SpecificComponent : IComponentBase<ComponentGuid>, IComponent<ComponentGuid>
{
public IEnumerable<ComponentGuid> List()
{
throw new System.NotImplementedException();
}
public void AddToList(ComponentGuid item)
{
throw new System.NotImplementedException();
}
}
public class P
{
public P(IComponentBase<IComponentGuid> pComponentBase) { }
}
class Caller
{
public Caller()
{
var specific = new SpecificComponent();
var p = new P(specific);
}
}
}