对于我项目中的所有实体,我都有一个基本实体,从该接口另一个接口,然后是一个类(这就是它的方式,我无法更改它(。
给定任何两个对象,我想调用一个方法。我创建了一个带有元组钥匙的字典,以便能够检索正确的方法。
这是代码:
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}");
}
不确定如何声明字典的键,因为呼叫失败了:"给定键不存在于字典中。"
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);
我已经使用了struct作为字典的键
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;
}
}