【发布时间】:2014-06-17 17:40:01
【问题描述】:
黑板是在运行时存储和获取通用键值对的对象。它可以通过Dictionary<object,object> 实现。一些子系统写入黑板以让其他子系统从中读取。
存储黑板的系统不知道里面是什么类型的物体,什么时候。特定键的写入者和读取者总是知道并同意键值对的类型。为了易于实现而牺牲了编译时检查 - 有许多编写者和阅读者,并且他们不断迭代。
我的黑板界面是这样的:
interface Blackboard {
bool HasKey(object key);
T GetValue<T>(object key);
}
编写者创建并返回黑板,因此SetValue(key, value) 可以是一个实现细节。
我最初的实现使用了Dictionary<object,object>,一切都很好。但是,这个黑板必须是快速且无分配的。这是没有商量余地的。如果作者将一个浮点值推入黑板,天真的实现将 int 装箱以放入字典中。
我不能在实现类BlackboardImpl<ValueType> : Blackboard 上使用泛型类型,因为值类型在黑板上不是恒定的。
我可以使用多个内部字典,Dictionary<object,float>、Dictionary<object,int> 等,带有备用Dictionary<object,object>,以及许多 SetValue 函数,所以现在我不会在插入时装箱。但是由于GetValue函数来自于接口,所以我不能对其进行约束,所以我仍然在退出时装箱:
T GetValue<T>(object key) {
if (typeof(T) == typeof(int)) {
// return intStore[key]; // doesn't compile
return (T)(object)intStore[key]; // boxes, allocates, bad.
}
// ...
}
我在这里是否缺少任何语法技巧,包括更改黑板界面以避免拳击?任何反射黑客都会违反“快速”要求,即使您可以在没有分配的情况下实现它。
干杯。
【问题讨论】:
-
@NicoSchertler:不,使用
dynamic肯定会装箱。 -
@JonSkeet:好的,我不确定。删除了评论。
-
您可以尝试将
void*与unsafe一起使用吗?