【问题标题】:C++/CLI: Implementing an abstract C# class that implements INotifyPropertyChanged results in C++ compiler error C3766C++/CLI:实现实现 INotifyPropertyChanged 的​​抽象 C# 类导致 C++ 编译器错误 C3766
【发布时间】:2013-05-16 05:47:57
【问题描述】:

我正在尝试在 C++/CLI 中实现一个抽象的 C# 类。这个抽象基类已经实现了 INotifyPropertyChanged 并且正如提到的用 C# 编写的:

public abstract class BaseClass : INotifyPropertyChanged

在 C++/CLI 程序集中,我确实有另一个实现 INotifyPropertyChanged 的​​接口:

public interface class IAnotherNotifyPropertyChangedClass : public INotifyPropertyChanged

现在,当从抽象 C# 类 BaseClass 继承并在 C++/CLI 中实现 IAnotherNotifyPropertyChangedClass 时,我得到以下信息:

public ref class AnotherNotifyPropertyChangedClass : public BaseClass, public IAnotherNotifyPropertyChangedClass

这会导致以下编译错误:

error C3766: 'AnotherNotifyPropertyChangedClass' must provide an implementation for the interface method 'void System::ComponentModel::INotifyPropertyChanged::PropertyChanged::add(System::ComponentModel::PropertyChangedEventHandler ^)'

一旦我从 IAnotherNotifyPropertyChangedClass 接口声明中删除 INotifyPropertyChanged,一切都编译得很好。这是为什么?使用 C# 时,此声明可以正常编译。我正在使用 VS 2012 并编译一个 .NET 3.5 混合模式程序集。

提前致谢!

干杯!

编辑: 类似的问题(没有 C#)在这里:http://social.msdn.microsoft.com/Forums/en-US/winappswithnativecode/thread/3047b8d1-348c-4ca6-b3f3-c396c03fedf7/ 那么这种行为在 C++/CLI 中是否是设计使然?!

【问题讨论】:

    标签: c# c++ .net c++-cli mixed-mode


    【解决方案1】:

    这是不正常的,我没有得到重现。问题没有显示实际代码,我会显示我的:

    C# 测试类:

    using System.ComponentModel;
    
    namespace ClassLibrary8 {
        public abstract class CFoo : INotifyPropertyChanged {
            public event PropertyChangedEventHandler PropertyChanged;
        }
    }
    

    C++/CLI 测试代码,添加到 C# 项目的引用后:

    using namespace System::ComponentModel;
    
    public interface class IBar : public INotifyPropertyChanged {
    };
    
    public ref class Baz : ClassLibrary8::CFoo, IBar {
        // fine
    };
    

    【讨论】:

    • 这正是我实现类的方式。唯一的区别是 CFoo 采用类型参数并读取“CFoo”。在纯 C# 中执行 C++/CLI 代码时,一切都按预期工作。你也在用VS2012和3.5吗?
    • 我可以尝试再次复制。但这很可能只是浪费我的时间,因为还有一个你没有提到的细节。您必须发布一个 SSCCE snippet 来证明问题以获得帮助。
    【解决方案2】:

    您需要做的是在您的 C++/CLI 类中显式实现 INotifyPropertyChanged。您可以让它调用已经实现的 C# 版本。

    我不能 100% 确定在您的情况下,您可能必须明确实现 AnotherNotifyPropertyChangedClass::PropertyChanged 而不是 INotifyPropertyChanged::PropertyChanged

    private:
        event PropertyChangedEventHandler^ DuplicatePropertyChanged
        {
            virtual void add (PropertyChangedEventHandler^ value) sealed = 
                INotifyPropertyChanged::PropertyChanged::add
            {
                // Add to the event defined in the C# class.
                this->PropertyChanged += value;
            }
    
            virtual void remove (PropertyChangedEventHandler^ value) sealed = 
                INotifyPropertyChanged::PropertyChanged::remove
            {
                // Remove from the event defined in the C# class.
                this->PropertyChanged -= value;
            }
        }
    

    【讨论】:

    • 我明白你的意思。这只是在做编译器要我做的事情,但是为什么在 C# 中实现 C++/CLI 类时不需要这样做?
    【解决方案3】:

    那是因为接口需要这样的实现:

    #region INotifyPropertyChanged Members
    public event PropertyChangedEventHandler PropertyChanged;
    #endregion
    

    因为 C# 类是抽象的,所以它不需要(必须)处理它,您需要在 C++ 类中实现它。那是第一个非抽象类。

    【讨论】:

    • 用 C# 编写的抽象类正在实现该接口。在纯 C# 中执行相同的场景(声明另一个接口继承 INotifyPropertyChanged 并在基类之上实现它)就像一个魅力......
    • 如果有两个 INotifyPropertyChanged 实现,我想说什么。这与公共 IEnumerator GetEnumerator() 和 IEnumerable.GetEnumerator() 的情况类似,您需要两者都可用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-23
    • 2012-05-03
    相关资源
    最近更新 更多