Delegate Variance in c++/cli
I am in the process of converting working C# code into C++/CLI, and I'm having trouble u开发者_运维技巧nderstanding why it does not compile.
The error I received:
void MyNamespace::Handler::DataChanged(System::Object ^,System::EventArgs ^)' : the specified function does not match the delegate type 'void (System::Object ^,System::Data::DataRowChangeEventArgs ^)'
Looks like C++/CLI doesn't support parameter variance for delegates as C# and VB do, see this Microsoft connect bug report.
As a work around your can wrap your call to handler in a wrapper that takes a DataRowChangeEventArgs and calls your handler:
public ref class MyClass
{
....
public:
void MyClass::Delegates(DataTable ^table)
{
Handler ^handler = gcnew Handler();
DataRowChangeEventForwarder& forwarder =
gcnew DataRowChangeEventForwarder(
new EventHandler(handler, &MyNamespace::Handler::DataChanged)));
table->RowChanged += gcnew DataRowChangeEventHandler (forwarder, &MyNamespace::MyClass::RowChangedDelegate);
}
}
public ref class DataRowChangeEventForwarder
{
private:
EventHandler^ eventHandler;
public:
EventForwarder(EventHandler^ eventHandler)
{
this->eventHandler = eventHander;
}
void MyClass::RowChangedDelegate(Object ^sender, DataRowEventArgs ^arg)
{
handler->DataChanged(sender, arg);
}
}
Here is a complete compile-ready reproduction of the bug (would be a comment, but the formatting would be horrid):
public ref struct A
{
};
public ref struct B : A
{
};
public ref struct C
{
delegate void DType(B^);
void F(A^ a) { };
};
int main(void)
{
C^ c = gcnew C;
C::DType^ del = gcnew C::DType(c, &C::F);
}
精彩评论