.NET事件拒绝使用byref参数委托

3

这真是让我头疼。

我已经阅读了关于此主题的SO帖子:这里是最相关的,但它没有涉及将委托传递给事件(尽管我本来以为会很简单)。

具体而言,在VS中出现的错误是:

This function value is being used to construct a delegate type whose signature includes a byref argument. You must use an explicit lambda expression taking 2 arguments.

我能找到的最好的错误解释是在Eric Lippert的博客中,但我认为下面已经解决了这个问题。
// Documentation: http://msdn.microsoft.com/en-us/library/aa752084(v=vs.85).aspx    
// Don't forget to unwrap the instance before using it.
let mutable ieInstance : option<InternetExplorer> = None

let onDocumentComplete (pDisp : Object) (url : byref<Object>) =
    let doc = ieInstance.Value.Document :?> IHTMLDocument2
    let window = doc.parentWindow
    window.execScript(@"alert('Message added by addon.');") |> ignore

// All of the following underline "DocumentComplete" as the source of the error.
do ieInstance.Value.DocumentComplete.AddHandler(new Handler<byref<Object>>(fun pDisp url -> onDocumentComplete pDisp &url))
do ieInstance.Value.DocumentComplete.AddHandler(fun pDisp url -> onDocumentComplete pDisp &url)
do ieInstance.Value.DocumentComplete.Add(fun pDisp url -> onDocumentComplete pDisp &url)
do ieInstance.Value.DocumentComplete.Add(fun _ _ -> ())
do ieInstance.Value.DocumentComplete.Add(fun (_, _) -> ())

我很感激任何建议!

更新1 我正在引用的库是Interop.SHDocVw,在“Microsoft Internet Controls”中。我还尝试使用SHDocVw.DWebBrowserEvents2_DocumentCompleteEventHandler作为委托类型,但仍然失败。


你在使用InternetExplorer类时,具体引用了哪个库? - Ryan Lundy
看起来像一种 COM 互操作类,但是文档链接没有说明具体是什么。 - Tahir Hassan
1
它是Interop.SHDocVw的一部分,位于程序集“Microsoft Internet Controls”中。它可以转换为诸如IWebBrowser2DWebBrowserEvents2等接口。 - dan p
请注意,您还需要引用 COM 组件“Microsoft HTML Object Library”,以及 mshtmlSystemSHDocVwopen 语句。 - latkin
1个回答

6
我得到的错误略有不同:

我得到的错误略有不同:

error FS1091: The event 'DocumentComplete' has a non-standard type. If this event is declared in another CLI language, you may need to access this event using the explicit add_DocumentComplete and remove_DocumentComplete methods for the event. If this event is declared in F#, make the type of the event an instantiation of either 'IDelegateEvent<_>' or 'IEvent<_,_>'.

如果您按照这个建议操作,您可以得到以下代码,这段代码对我来说可以编译成功:
ieInstance.Value.add_DocumentComplete(fun pDisp url -> onDocumentComplete pDisp &url)

编辑

Keith和Tahir的评论让我意识到 - 这个场景确实很难诊断,事实上,在F# 3.1.1发布后不久就已经修复了。

新行为是更好的错误消息(如上所示),以及更好的智能感知条目(现在显示必需的add_remove_成员,并且无用的DocumentComplete条目现在实际上被隐藏了)。如果你正在使用发布的 F# 程序包,则抱歉。如果你正在使用最新的预发行版 F# 程序包,则会少一些痛苦。

这个变化是在 Codeplex 上所有东西变成开源之前就进行了,但是它的一些记录仍然可以在后来合并到 Github 的提交中看到(参见 infos.fs 和 nameres.fs 中的最后一次更改)。


1
我遇到了和dan p一样的错误,但是你提出的解决方案仍然有效(即使add_DocumentComplete在IntelliSense中没有出现)。 - kvb
1
在VS 2013中,F# Intellisense不会列出add_DocumentComplete。但是在VS 14 CTP中我看到了它。很奇怪。 - Tahir Hassan
我因为同样的问题而疯狂。我有VS 2010,但智能感知没有显示add_DocumentComplete,尽管它说它实现了Events2接口。浪费了三个小时后,很高兴我找到了这个页面。 - user2074102

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接