c++/cli 中的委托方差

发布于 2024-11-25 17:29:24 字数 237 浏览 1 评论 0原文

我正在将工作 C# 代码转换为 C++/CLI,但我无法理解它为何无法编译。

我收到的错误:

void MyNamespace::Handler::DataChanged(System::Object ^,System::EventArgs ^)':指定的函数与委托类型'void (System::Object ^,System ::Data::DataRowChangeEventArgs ^)'

I am in the process of converting working C# code into C++/CLI, and I'm having trouble understanding 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 ^)'

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

后eg是否自 2024-12-02 17:29:24

看起来 C++/CLI 不像 C# 和 VB 那样支持委托的参数变化,请参阅 此 Microsoft connect 错误报告

作为解决方法,您可以将对处理程序的调用包装在一个包装器中,该包装器采用 DataRowChangeEventArgs 并调用您的处理程序:

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);
     }
 }

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);
     }
 }
南风几经秋 2024-12-02 17:29:24

这是该错误的完整可编译再现(可能是注释,但格式会很糟糕):

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);
}

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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文