COM 互操作 - 事件和 属性 同名
COM interop - event and property with same name
我有一个用 C++/ATL 实现的旧 COM 对象。该对象有一个事件和一个同名的 属性。这在 COM 中不是问题。
在 C# 中,属性 有效地隐藏了事件,因此似乎无法添加事件处理程序。
这个问题在 C# 中有解决方案吗?
(有趣的是,您可以使用 WithEvents 和 Handles 机制在 VB.NET 中处理它,但这对我在 C# 中没有帮助)。
更新
这是事件接口(IDL)的定义。
// Event interface to be implemented by channel objects.
[
uuid(FF34BE60-C584-4f45-B3A1-231F0E08BE83),
helpstring("IChannelEvents Interface"),
]
dispinterface IChannelEvents
{
properties:
methods:
[id(1), helpstring("")]
void OnlineValue ( [in] double dValue,
[in] double dMax,
[in] double dMin,
[in] BSTR Unit,
[in] VARIANT_BOOL bOverloaded );
[id(2), helpstring("")]
void MeasuredExcitation ( [in] double dValue,
[in] VARIANT_BOOL bValueValid,
[in] VARIANT_BOOL bInRange );
[id(3), helpstring("")]
void MultipleOnlineValues ( [in] VARIANT Values,
[in] BSTR Unit );
} ;
这是 COM 对象 (IDL) 的定义
[
uuid(2B725FC4-6FE6-4D53-9528-F098F04E98EE),
helpstring("Channel Class")
]
coclass Channel
{
[default] interface IChannel;
[default, source ] dispinterface IChannelEvents ;
};
接口 IChannel 包含一个 属性 名为 OnlineValue。我认为确切的定义并不重要。
汉斯似乎在暗示这样的事情:
class EventTest
{
void Test()
{
Channel c = null ;
IChannelEvents ce = c as IChannelEvents ;
ce.OnlineValue += this.OnlineValue ;
}
void OnlineValue ( double dValue,
double dMax,
double dMin,
string Unit,
bool bOverloaded )
{
}
}
这会产生错误
Error CS1656
Cannot assign to 'OnlineValue' because it is a 'method group'
这段代码对我来说并没有真正的意义,因为 - 正如 Hans 所说 - 通道对象没有实现事件接口,那么为什么从 Channel 到 IChannelEvents 的转换会起作用?
我找到了解决方案,这可能是 Hans Passant 的建议。
事件接口名为 IChannelEvents。类型库导入器生成一个名为 IChannelEvents_Event.
的接口
反汇编后,接口定义如下:
[ComEventInterface(typeof(IChannelEvents), typeof(IChannelEvents_EventProvider)), ComVisible(false), TypeLibType(16)]
public interface IChannelEvents_Event
{
event IChannelEvents_OnlineValueEventHandler OnlineValue;
event IChannelEvents_MeasuredExcitationEventHandler MeasuredExcitation;
event IChannelEvents_MultipleOnlineValuesEventHandler MultipleOnlineValues;
}
我可以将 COM 对象转换为该接口并添加一个事件处理程序,如下所示。
class EventTest
{
void Test()
{
Channel c = null ;
IChannelEvents_Event ee = c as IChannelEvents_Event ;
ee.OnlineValue += OnlineValue ;
}
void OnlineValue ( double dValue,
double dMax,
double dMin,
string Unit,
bool bOverloaded )
{
}
}
该界面在intellisense中不显示,但进入后,visual Studio设置文字颜色,表示识别类型
我有一个用 C++/ATL 实现的旧 COM 对象。该对象有一个事件和一个同名的 属性。这在 COM 中不是问题。
在 C# 中,属性 有效地隐藏了事件,因此似乎无法添加事件处理程序。
这个问题在 C# 中有解决方案吗?
(有趣的是,您可以使用 WithEvents 和 Handles 机制在 VB.NET 中处理它,但这对我在 C# 中没有帮助)。
更新
这是事件接口(IDL)的定义。
// Event interface to be implemented by channel objects.
[
uuid(FF34BE60-C584-4f45-B3A1-231F0E08BE83),
helpstring("IChannelEvents Interface"),
]
dispinterface IChannelEvents
{
properties:
methods:
[id(1), helpstring("")]
void OnlineValue ( [in] double dValue,
[in] double dMax,
[in] double dMin,
[in] BSTR Unit,
[in] VARIANT_BOOL bOverloaded );
[id(2), helpstring("")]
void MeasuredExcitation ( [in] double dValue,
[in] VARIANT_BOOL bValueValid,
[in] VARIANT_BOOL bInRange );
[id(3), helpstring("")]
void MultipleOnlineValues ( [in] VARIANT Values,
[in] BSTR Unit );
} ;
这是 COM 对象 (IDL) 的定义
[
uuid(2B725FC4-6FE6-4D53-9528-F098F04E98EE),
helpstring("Channel Class")
]
coclass Channel
{
[default] interface IChannel;
[default, source ] dispinterface IChannelEvents ;
};
接口 IChannel 包含一个 属性 名为 OnlineValue。我认为确切的定义并不重要。
汉斯似乎在暗示这样的事情:
class EventTest
{
void Test()
{
Channel c = null ;
IChannelEvents ce = c as IChannelEvents ;
ce.OnlineValue += this.OnlineValue ;
}
void OnlineValue ( double dValue,
double dMax,
double dMin,
string Unit,
bool bOverloaded )
{
}
}
这会产生错误
Error CS1656
Cannot assign to 'OnlineValue' because it is a 'method group'
这段代码对我来说并没有真正的意义,因为 - 正如 Hans 所说 - 通道对象没有实现事件接口,那么为什么从 Channel 到 IChannelEvents 的转换会起作用?
我找到了解决方案,这可能是 Hans Passant 的建议。
事件接口名为 IChannelEvents。类型库导入器生成一个名为 IChannelEvents_Event.
的接口反汇编后,接口定义如下:
[ComEventInterface(typeof(IChannelEvents), typeof(IChannelEvents_EventProvider)), ComVisible(false), TypeLibType(16)]
public interface IChannelEvents_Event
{
event IChannelEvents_OnlineValueEventHandler OnlineValue;
event IChannelEvents_MeasuredExcitationEventHandler MeasuredExcitation;
event IChannelEvents_MultipleOnlineValuesEventHandler MultipleOnlineValues;
}
我可以将 COM 对象转换为该接口并添加一个事件处理程序,如下所示。
class EventTest
{
void Test()
{
Channel c = null ;
IChannelEvents_Event ee = c as IChannelEvents_Event ;
ee.OnlineValue += OnlineValue ;
}
void OnlineValue ( double dValue,
double dMax,
double dMin,
string Unit,
bool bOverloaded )
{
}
}
该界面在intellisense中不显示,但进入后,visual Studio设置文字颜色,表示识别类型