我在c#中将com对象定义为动态类型我能够非常轻松地调用方法.但是,当我尝试访问同一对象上的属性时,我得到一个无效的强制转换异常.
有问题的对象是一个数组,从JavaScript传递给托管代码,我希望将它的长度属性作为int.
我知道我遗漏了一些奇怪的东西,因为我没有得到"不包含定义"的异常,我可以使用reflection/InvokeMember轻松访问该属性.
为什么我不能将动态类型的length属性转换为int?
例如
这很失败
dynamic com = comObject;
int i = com.length; // RTBE here.
Run Code Online (Sandbox Code Playgroud)
这个作品
Type type = comObject.GetType();
int i = (int)type.InvokeMember("length", BindingFlags.GetProperty, null, comObject, null);
Run Code Online (Sandbox Code Playgroud)
*更新*
经过大量的测试后,我将这种奇怪的范围缩小到了多维数组的情况.有问题的com对象是从html文档传递到托管代码的参数.对于所有意图和目的,对象有时在JavaScript中看起来像这样.
var x = ["a1", "a2", "a3"];
Run Code Online (Sandbox Code Playgroud)
当像这样的数组进入托管代码时,我可以使用动态类型获得长度AOK.(即这里的第一个例子实际上无效).但是,如果它是一个多维数组,例如JavaScript中的以下结构.
var y = [["b1", "b2", "b3"], "a2", "a3"];
Run Code Online (Sandbox Code Playgroud)
然后我尝试动态访问其长度属性时出错.注意,在这种情况下,我仍然可以通过反射访问长度.在我看来,由于某种原因,当多维数组用作动态类型时,长度属性无法正确映射...
在我的情况下,我已经做了解决(!?)这是在传递它之前向数组添加'length_'属性.
var y = [["b1", "b2", "b3"], "a2", "a3"];
y.length_ = y.length;
Run Code Online (Sandbox Code Playgroud)
现在在托管代码中,我可以按预期访问此属性而不会出现错误.远非理想,但似乎工作......
dynamic com = comObject;
int i = com.length_; // 3!
Run Code Online (Sandbox Code Playgroud)
进一步更新
好的,所以似乎除了属性之外,对象索引也会丢失到动态类型中.再次通过反射可以访问...
失败
dynamic com = comObject; // js …Run Code Online (Sandbox Code Playgroud)