C#4中的dynamic关键字引入了处理以前无法实现的对象的新方法。 这与泛型有何重叠? 具体来说,是否有一些可能有用的操作现在合法有效? 例如,现在不可能: dynamic可用后,是否有办法完成类似的任务? ...
提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供 中文繁体 英文版本 中英对照 版本,有任何建议请联系yoyou2525@163.com。
我在c#中将com对象定义为动态类型我能够非常轻松地调用方法。 但是,当我尝试访问同一对象上的属性时,我得到一个无效的强制转换异常。
有问题的对象是一个数组,从JavaScript传递给托管代码,我希望将它的长度属性作为int。
我知道我遗漏了一些奇怪的东西,因为我没有得到“不包含定义”的异常,我可以使用reflection / InvokeMember轻松访问该属性。
为什么我不能将动态类型的length属性转换为int?
例如
这很失败
dynamic com = comObject;
int i = com.length; // RTBE here.
这个作品
Type type = comObject.GetType();
int i = (int)type.InvokeMember("length", BindingFlags.GetProperty, null, comObject, null);
*更新*
经过大量的测试后,我将这种奇怪的范围缩小到了多维数组的情况。 有问题的com对象是从html文档传递到托管代码的参数。 对于所有意图和目的,对象有时在JavaScript中看起来像这样。
var x = ["a1", "a2", "a3"];
当像这样的数组进入托管代码时,我可以使用动态类型获得长度AOK。 (即这里的第一个例子实际上无效)。 但是,如果它是一个多维数组,例如JavaScript中的以下结构。
var y = [["b1", "b2", "b3"], "a2", "a3"];
然后在尝试动态访问其length属性时出现错误。 注意,在这种情况下,我仍然可以通过反射访问长度。 在我看来,由于某种原因,当多维数组用作动态类型时,长度属性无法正确映射...
在我的情况下,我已经做了解决(!?)这是在传递它之前向数组添加'length_'属性。
var y = [["b1", "b2", "b3"], "a2", "a3"];
y.length_ = y.length;
现在在托管代码中,我可以按预期访问此属性而不会出现错误。 远非理想,但似乎工作......
dynamic com = comObject;
int i = com.length_; // 3!
进一步更新
好的,所以似乎除了属性之外,对象索引也会丢失到动态类型中。 再次通过反射可以访问...
失败
dynamic com = comObject; // js array i.e. var x = [1, 2];
int i = com[0]; // MissingMemberException - Error while invoking [PROPERTYGET, DISPID(0)].
int i = com["0"]; // MissingMemberException - Error while invoking [PROPERTYGET, DISPID(0)].
作品
Type type = comObject.GetType();
int i = (int)type.InvokeMember("0", BindingFlags.GetProperty, null, comObject, null); // 1
简单来说,你不能通过动态类型访问c#中多维数组的length属性,除非看起来你先在JavaScript中使用了length属性...
下面的简单测试非常清楚地显示了这一点 我希望这可以节省其他人在最后一天左右的头部刮伤。
[ComVisibleAttribute(true)]
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
webBrowser1.ObjectForScripting = this;
StringBuilder html = new StringBuilder();
html.Append("<script>");
html.Append("var arr1 = [1, 2, 3, 4];");
html.Append("var arr2 = [arr1, 2, 3, 4];");
html.Append("var fn1 = function() { return arr1; };");
html.Append("var fn2 = function() { return arr2; };");
html.Append("var fn3 = function() { alert(arr2.length); }");
html.Append("</script>");
webBrowser1.DocumentText = html.ToString();
webBrowser1.DocumentCompleted += (o, e) =>
{
dynamic arr1 = webBrowser1.Document.InvokeScript("fn1");
int i = arr1.length;
MessageBox.Show(i.ToString()); //4
// If I call fn3 here then the arr2.length *is* available as int i2 below!
////webBrowser1.Document.InvokeScript("fn3"); // 4
dynamic arr2 = webBrowser1.Document.InvokeScript("fn2");
int i2 = arr2.length;
MessageBox.Show(i2.ToString()); // unless fn3 is called you get...
/*
System.MissingMemberException was unhandled by user code
Message=Error while invoking length.
Source=System.Dynamic
StackTrace:
at System.Dynamic.ComRuntimeHelpers.CheckThrowException(Int32 hresult, ExcepInfo& excepInfo, UInt32 argErr, String message)
at CallSite.Target(Closure , CallSite , ComObject )
at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0)
at CallSite.Target(Closure , CallSite , Object )
at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0)
*/
};
}
}
更新
似乎(见注释)如果WebBrowser控件使用Internet Explorer版本9(...控件使用计算机上的IE版本),则此行为是固定的。 我只能假设IE9'Chakra'JavaScript引擎在这种情况下对旧的js引擎做了额外/不同的事情。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.