在C#中,Dictionary
类只使用一个键并将其映射到单个值。我正在寻找类似的东西,我可以在其中传递一个有序的元组并获得单个值 - 没有将它包装在一个类中。
这是我想要的一个非常假设的例子(使用按钮,而不是某些2D地图图块)。目前,我可以这样做:
Dictionary<int, Button> buttons = new Dictionary<int, Button>();
如果我想使用每个按钮的坐标作为键,我可以这样做:
Dictionary<Point, Button> buttons = new Dictionary<Point, Button>();
buttons[new Point(b.X, b.Y)] = b;
我想做的是这个
Dictionary<int, int, Button> buttons = new Dictionary<int, int, Button>();
buttons[b.X, b.Y] = b;
同样,这是一个简单的案例,有一个已知的解决方法。但我觉得很烦人,我必须创建一个新的占位符类(struct?),其中包含我想用作关键字的每组参数。
这有可能吗?
答案 0 :(得分:5)
public class TupleDictionary<T1, T2, TValue> : Dictionary<Tuple<T1,T2>,TValue>
{
public TValue this[T1 t1, T2 t2]
{
get { return this[new Tuple<T1, T2>(t1, t2)]; }
set { this[new Tuple<T1, T2>(t1,t2)] = value; }
}
public void Add(T1 t1, T2 t2, TValue value)
{
Add(new Tuple<T1, T2>(t1, t2), value);
}
public void Remove(T1 t1, T2 t2)
{
Remove(new Tuple<T1, T2>(t1, t2));
}
public bool ContainsKey(T1 t1, T2 t2)
{
return ContainsKey(new Tuple<T1, T2>(t1, t2));
}
public bool TryGetValue(T1 t1, T2 t2, out TValue value)
{
return TryGetValue(new Tuple<T1, T2>(t1, t2), out value);
}
}
答案 1 :(得分:2)
在.Net 4中,您可以使用元组作为字典键
Dictionary<Tuple<int, int>, Button> buttons = new Dictionary<Tuple<int, int>, Button>();
buttons[new Tuple<int,int>(b.X, b.Y)] = b;
答案 2 :(得分:2)
这是扩展方法可能有用的情况。
我编写了一堆字典扩展方法,允许GetOrAdd
和GetOrDefault
等函数在标准字典上工作,这有助于减少检查项目是否已存在于字典中的所有噪音
同样,您可以使用扩展方法扩展嵌套字典。
所以,也许你可以编写这样的代码:
var buttons = new Dictionary<int, Dictionary<int, Button>>();
buttons.Add(b.X, b.Y, b);
buttons.AddOrReplace(b1.X, b1.Y, b1);
我的Add
方法如下所示:
public static void Add<K1, K2, V>(
this IDictionary<K1, Dictionary<K2, V>> @this,
K1 key1,
K2 key2,
V value)
{
if (@this == null) { throw new ArgumentNullException("@this"); }
if (key1 == null) { throw new ArgumentNullException("key1"); }
if (key2 == null) { throw new ArgumentNullException("key2"); }
if (!@this.ContainsKey(key1))
{
@this[key1] = new Dictionary<K2, V>();
}
@this[key1][key2] = value;
}
这种方法很不错,因为您仍在使用标准.NET词典,但只需要相对较小的语法差异即可获得您所使用的功能。
另一种方法是定义自己的类字典类。像这样:
public class TupleDictionary<K1, K2, V>
{
public void Add(K1 key1, K2 key2, V value);
public bool ContainsKey(K1 key1, K2 key2);
public bool Remove(K1 key1, K2 key2);
public Dictionary<K2, V> this[K1 key1] { get; }
}
然后,因为this
索引属性将“获取或添加”内部词典,您可以像这样编写代码:
var td = new TupleDictionary<int, int, Button>();
td[b.X][b.Y] = b;
从语法上讲,它看起来与您的示例代码相同,但您需要编写大量代码才能获得此特定语法。
我认为使用嵌套字典的扩展方法是可行的方法。