【发布时间】:2011-08-03 09:50:41
【问题描述】:
我有一个ConfigValue 类型,它通过IDynamicMetaObjectProvider 的实现和自定义DynamicMetaObject 实例公开一个动态接口。
当然,这种类型的实例可以看作是本机类型 - 类似于 XML 元素 - 但根据 XML 的内容和内容,它也可以看作任何其他对象类型的实例它构建的对象类型(它是由小老我构建的专有 IOC)。
所以
<value>10</value>
可以被视为ConfigValue,但也可能被视为string、short、double 等。转换是通过调用语言指定的隐式或显式转换实现的。 XML 变得更加复杂,因为您可以触发构造函数、方法、属性获取等。
为了实现这一点,当然,我已经覆盖了 DynamicMetaObject 类型的 BindConvert 成员 - 如果在运行时 ConfigValue 对象不支持转换,则会发生运行时错误(这很好) .
我刚刚开始编写一段代码,如果我可以对目标类型进行安全强制转换,那就太好了,但如果这不起作用,则回退到其他逻辑 - 类似于:
public DesiredType Foo(dynamic d)
{
DesiredType dt = d as dt;
if(dt != null)
return dt;
//TODO: Fallback logic to build dt from d
}
但是,至少 C#(我敢肯定可能是所有动态感知语言)不会为“as”或“is”操作发出任何动态绑定;大概是因为DynamicMetaObject 没有进行此类测试的方法。因此,类型测试只是对静态类型信息执行,在这种情况下,总是失败。
因此我不得不依赖相当丑陋的东西:
public DesiredType Foo(dynamic d)
{
try
{
return (DesiredType)d;
}
catch(Exception)
{
//TODO: fallback logic
}
}
有什么想法可以在这里避免 try/catch/gulp 模式!?我能想到的最好的东西是DynamicMetaObject之上的东西;但是必须先查询,然后再查询类型测试;这只会使代码进一步爆炸!
【问题讨论】:
-
我尝试在
DynamicObject的TryBinaryOperation方法中检查ExpressionType.TypeIs。不走运 - C# 编译器总是发出 IL。我认为最好的办法是提供Is(Type)和Is<T>()方法。虽然请记住,演员阵容仍然可以解决问题 (TryConvertTo),因此您可以只使用演员阵容而不是ass。 -
@Jonathan - 最后我用静态方法完成了它,而不是扩展动态对象/提供者。我想知道是否有将这种能力添加到 DLR 的案例……可能不会!
-
我真的认为你应该在connect.microsoft.com 上打开它——这是一个缺点(考虑到
ExpressionType枚举具有TypeIs值)。 -
@Jonathan - 你是对的 - 到目前为止我的命中率是 50/50,所以我可以这样做!
-
你能展示你对 BindConvert 的覆盖是如何工作的吗?谢谢。