为什么我要投从动态的未来结果为键入参数

问题描述:

我有一个简单的动态对象,返回一个double:为什么我要投从动态的未来结果为键入参数

class MyDynamic : DynamicObject 
{ 
    public override bool TryGetMember(GetMemberBinder binder, out object result) 
    { 
     result = 2.0; 
     return true; 
    } 
} 

然后,我尝试调用接受一个int的方法:

private static void SomeMethod(int number) 
    { 

    } 

然后,我打个电话,并通过从dynamic我的价值,进入方法:

 dynamic x = new MyDynamic(); 
     SomeMethod(x.number); 

现在,这会导致异常,因为运行时会抱怨找不到相关的方法。这是预期的行为?我希望运行时能够自动将返回的值转换为方法请求的类型(int,在本例中)。

这是怎么东西应该工作?

+0

如果您编辑问题以提供一个简短但完整的程序来展示问题,而不仅仅是片段 - 并在您的问题中显示完整的例外情况,这将会很有帮助。 – 2015-01-15 17:20:25

我会期望运行时自动将返回的值转换为方法所要求的类型(在本例中为int)。

为什么你会期望它做到这一点?通常不存在从doubleint的隐式转换,那么您为什么期望它在动态类型的上下文中?

换一种方式 - 如果x.number静态类型返回double,你会得到一个编译时失败。使用动态类型时的执行时失败是镜像相同的失败。基本上,找到正确的调用方法的尝试被推迟到执行时间,此时参数的类型是已知的。参数的类型结果是double,并且没有从doubleint的隐式转换,所以您会收到异常。

如果你尝试它倒过来 - 提供在TryGetMemberint,然后调用接受的方法double - 然后隐式转换应该踢在

注意,您可以使用显式转换,从double。到int与铸造:

SomeMethod((int) x.number); 

这就使得重载在编译时,和刚的x.number到转换在执行时...这在这里很好,因为显式转换从doubleint存在。

注意,您不必使用一种方法来证明这一点:

int y = x.number; // Fails at execution time 
int z = (int) x.number; // Works 

基本上,从doubleint转化为明确的,并且你要明确的是需要在动态类型的坚持太。

+0

这很有道理。谢谢。我过度期待动态行为更像动态语言(您希望这种转换会自动发生)。因为在一天结束时,'dynamic'的DLR位需要与严格类型的C#代码进行交互,这是完全合理的。谢谢。 – 2015-01-15 18:44:41

+0

@ShaharPrish - 即使在动态语言中,它们也不仅允许对类型进行无所不在的转换,而且可以在不引发某种错误的情况下导致数据丢失(至少不会出现任何体面的动态语言)。你会期待什么?它只是截断小数,并没有告诉你它?这是一个巨大而潜在的灾难性错误,正在等待发生。 – 2015-01-15 19:51:02

+0

嗯..很多动态语言都允许这样(尽管你的“体面”位允许你打折全部)。当与COM对象交谈时(当然不是语言本身,但内置在它中的扩展以允许通信)只会透明地执行此操作。与vbscript一样。与VB/VBA一样。大多数风格或SQL都是一种脚本语言。其他常见的动态语言/脚本没有int和double的定义,所以很难找到相关示例。 – 2015-01-15 22:08:42