我有几本词典:
Dictionary<int, Type1> Type1Dictionary { get; set; }
Dictionary<int, Type2> Type2Dictionary { get; set; }
Dictionary<int, Type3> Type3Dictionary { get; set; }
Dictionary<int, Type4> Type4Dictionary { get; set; }
其中Typei (i = 1..4)
派生自同一基类(BaseType
)。我想要一个方法,返回给定类型的字典的引用。稍后,我将在该字典上执行一些操作,如添加或删除:
Type1 example = new Type1();
var dic = GetDictionary(example);
dic.Add(example.ID, example);
注意:我不想将我的词典设为Dictionary<int, BaseType>
我可以写这样的东西但是不会返回对字典的引用:
Dictionary<int, BaseType> GetDictionary(BaseType myObject)
{
var dic = new Dictionary<int, BaseType>();
if(myObject is Type1)
{
//ideally I would return my Type1Dictionary here but I can't due type incompatibility
foreach(var x in Type1Dictionary)
{
dic.Add(x.Key, x.Value);
}
return dic;
}
if(myObject is Type2) { /*...*/ }
if(myObject is Type3) { /*...*/ }
if(myObject is Type4) { /*...*/ }
}
编辑:
我真正想要的是避免以下结构:
AddObject(BaseType x)
{
Type1 x1 = x as Type1;
if(x1 != null) { Type1Dictionary.Add(x1.ID, x1); }
Type2 x2 = x as Type2;
if(x2 != null) { Type2Dictionary.Add(x2.ID, x2); }
Type3 x3 = x as Type3;
if(x3 != null) { Type3Dictionary.Add(x3.ID, x3); }
Type4 x4 = x as Type4;
if(x4 != null) { Type4Dictionary.Add(x4.ID, x4); }
}
RemoveObject(BaseType x)
{
Type1 x1 = x as Type1;
if(x1 != null) { Type1Dictionary.Remove(x1.ID); }
Type2 x2 = x as Type2;
if(x2 != null) { Type2Dictionary.Remove(x2.ID); }
Type3 x3 = x as Type3;
if(x3 != null) { Type3Dictionary.Remove(x3.ID); }
Type4 x4 = x as Type4;
if(x4 != null) { Type4Dictionary.Remove(x4.ID); }
}
但相反:
AddObject(BaseType x)
{
var dic = GetDictionary(x);
dic.Add(x.ID, x);
}
RemoveObject(BaseType x)
{
var dic = GetDictionary(x);
dic.Remove(x.ID);
}
答案 0 :(得分:5)
这可以在安全性等方面得到完善。但是你应该能够得到基本的想法:
public interface IEntity
{
int ID { get; }
}
public class Superset<T> where T : IEntity
{
public Dictionary<Type, Dictionary<int, T>> m_Map =
new Dictionary<Type, Dictionary<int, T>>();
private Dictionary<int, T> GetDictionary(Type t)
{
Dictionary<int, T> result = null;
if (!m_Map.TryGetValue(t, out result))
{
result = new Dictionary<int, T>();
m_Map.Add(t, result);
}
return result;
}
public void Add<K>(K item) where K : T
{
GetDictionary(typeof(K)).Add(item.ID, item);
}
public bool Remove<K>(K item) where K : T
{
return GetDictionary(typeof(K)).Remove(item.ID);
}
}
答案 1 :(得分:0)
DLR可以玩这些技巧:动态调度。它在运行时解析所需的方法。这允许您拥有许多强类型的字典,但是更通用的处理机制。我这样做是为了处理来自共同事件库的事件。
class Program
{
private static Dictionary<int, Foo> _foos = new Dictionary<int, Foo>();
private static Dictionary<int, Baz> _bazs = new Dictionary<int, Baz>();
static void Main(string[] args)
{
Bar foo = new Foo();
Bar baz = new Baz();
Add(foo); // Resolves at runtime to Add(Foo f)
Add(baz); // Resolves at runtime to Add(Baz b)
}
public static void Add(Bar b)
{
Add((dynamic)b);
}
private static void Add(Foo f)
{
_foos.Add(1, f);
}
private static void Add(Baz b)
{
_bazs.Add(1, b);
}
}
class Foo : Bar
{
}
class Baz : Bar
{
}
class Bar
{
}
将内容移入DLR还有其自身的缺陷(即编译时问题现在是运行时问题),因此需要进行审核。这只是一种方法。另一种方法是访问者模式的实现。另一种方法就是你现在所拥有的。
不要将此答案作为 方式来实现。