黑板是在运行时存储和获取通用键值对的对象.它可以通过a实现Dictionary<object,object>.有些子系统写入黑板,让其他子系统从中读取.
存储黑板的系统不知道其中包含什么类型的对象,何时.特定密钥的编写者和读者总是知道并同意键值对的类型.为了便于实现,牺牲了编译时检查 - 有许多编写器和读者,并且它们不断被迭代.
我的黑板界面如下所示:
interface Blackboard {
bool HasKey(object key);
T GetValue<T>(object key);
}
Run Code Online (Sandbox Code Playgroud)
作家创建并返回黑板,因此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.
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
有没有我在这里缺少的语法技巧,包括改变黑板界面,避免拳击?任何反射黑客都会违反"快速"要求,即使您可以在没有分配的情况下实施它.
干杯.
虽然我不想这样做(而且我需要说服拳击的成本确实会很大),但你可以拥有多个商店并Dictionary<object, T>在你的方法中有一个类型变量 - 这样我相信你避免拳击:
T GetValue<T>(object key)
{
Dictionary<object, T> store;
if (typeof(T) == typeof(int)
{
store = (Dictionary<object, T>) (object) intStore;
}
else if (typeof(T) == typeof(float))
{
store = (Dictionary<object, T>) (object) floatStore;
}
// etc - with a default or an error case for unhandled types.
return store[key];
}
Run Code Online (Sandbox Code Playgroud)
请注意,这里的双重强制转换对于让编译器满意是必要的,但它不涉及装箱。