如何确定不需要 MarshalByRefObject 的原因

How to determine why MarshalByRefObject is not required

一个COM过滤器的实现(here)class增加了对MarshalByRefObjectclass和IDisposable接口的依赖,如下:

class MessageFilter : MarshalByRefObject, IDisposable, IMessageFilter

MSDN implementation不使用这些:

class MessageFilter : IOleMessageFilter

我已经尝试了这两种实现方式,它们都有效。为什么 MSDN 实现不需要依赖项?它们是否可能是由于所涉及的 IOleMessageFilter 接口使用的属性而引入的?使用的属性是:

[ComImport()]
[Guid("00000016-0000-0000-C000-000000000046")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]

但是这两个实现都使用了这些,所以我很困惑。两种实现都指定了 [DllImport("Ole32.dll")],但 MSDN 实现不包含随附的 [PreserveSig].

IMO,MarshalByRefObject's implementation that would make it stand out vs mere Object for implementing COM IMessageFilter(又称 IOleMessageFilter)没有什么特别的。

也许,从 StandardOleMarshalObject, because (from here 推导出 MessageFilter 会更符合逻辑:

Only STA (APARTMENT_THREADED) threads may have message filters If CoRegisterMessageFilter is called on a thread which was initialized with COINIT_MULTITHREADED, then the return code is CO_E_NOT_SUPPORTED (0x80004021)

就是说,我也不确定 StandardOleMarshalObject 是否是必需的,因为 IMessageFilter 方法应该只在已注册 COM 消息过滤器的同一个 STA 线程上调用.

您可以在我最近的问题中阅读更多关于 StandardOleMarshalObjectObject 的信息:

在 Andrew Whitechapel 的 MSDN 博客中:

Andrew Whitechapel 在 IMessageFilter 上也有一个很棒的博客 post:

COM 是一种纯粹基于接口的编程范式。它完全不知道 class 长什么样,它只关心它实现了 IMessageFilter。这与接口在 C# 语言中的工作方式没有什么不同。

因此,如果程序员有充分的理由让 class 做的不仅仅是接收消息过滤器回调,那很好。我敢猜测他实施了 IDisposable 来恢复旧的消息过滤器。解释 MarshalByRefObject 变得相当困难,您必须深入研究源代码才能找到充分的理由。

COM 非常不同的是它完全不关心接口的名称。您可以随意命名它,唯一重要的是 [Guid]。 IMessageFilter 是 MSDN 文档中使用的名称,Visual Studio 伙计们可能想避免与 .NET IMessageFilter 类型发生冲突,它的作用完全不同。

所以是的,您的 class 工作正常是完全正常的。不要添加任何你不需要的东西。