0

I'm trying to implement an abstract C# class in C++/CLI. This abstract base class is already implementing INotifyPropertyChanged and as mentioned written in C#:

public abstract class BaseClass : INotifyPropertyChanged

In the C++/CLI assembly, I do have another interface that implements INotifyPropertyChanged:

public interface class IAnotherNotifyPropertyChangedClass : public INotifyPropertyChanged

Now, when inheriting from the abstract C# class BaseClass and implementing IAnotherNotifyPropertyChangedClass in C++/CLI I get the following:

public ref class AnotherNotifyPropertyChangedClass : public BaseClass, public IAnotherNotifyPropertyChangedClass

This results then in following compiling error:

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

As soon as I remove the INotifyPropertyChanged from IAnotherNotifyPropertyChangedClass interface declaration, everything compiles fine. Why is that? This declaration would compile fine when using C#. I'm using VS 2012 and compile a .NET 3.5 mixed mode assembly.

Thanks in advance!

Cheers!

Edit: Similar problem (w/o C#) here: http://social.msdn.microsoft.com/Forums/en-US/winappswithnativecode/thread/3047b8d1-348c-4ca6-b3f3-c396c03fedf7/ So is this behavior in C++/CLI by design?!

barnacleboy
  • 539
  • 8
  • 18

3 Answers3

3

This is not normal and I don't get a repro for this. The question doesn't show actual code, I'll show mine:

The C# test class:

using System.ComponentModel;

namespace ClassLibrary8 {
    public abstract class CFoo : INotifyPropertyChanged {
        public event PropertyChangedEventHandler PropertyChanged;
    }
}

The C++/CLI test code, after having a reference added to the C# project:

using namespace System::ComponentModel;

public interface class IBar : public INotifyPropertyChanged {
};

public ref class Baz : ClassLibrary8::CFoo, IBar {
    // fine
};
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • That's exactly how I've implemented the classes. The only difference is that CFoo takes a type parameter and reads "CFoo". When doing the C++/CLI code in pure C# everything works as expected. Are you using VS2012 and 3.5 too? – barnacleboy May 16 '13 at 06:29
  • 1
    I could try to repro that again. But that would likely be just an enormous waste of my time again when there's yet another detail you didn't mention. You *must* post an [SSCCE snippet](http://sscce.org/) that demonstrates the problem to get help. – Hans Passant May 16 '13 at 09:32
2

What you need to do is have an explicit implementation of INotifyPropertyChanged in your C++/CLI class. You can have it call to the already-implemented C# version.

I'm not 100% sure in your scenario, you may have to explicitly implement AnotherNotifyPropertyChangedClass::PropertyChanged instead of 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;
        }
    }
David Yaw
  • 27,383
  • 4
  • 60
  • 93
  • I see your point. This is just doing what the compiler wants me to do, but why is this not neccessary when implementing the C++/CLI class in C#? – barnacleboy May 16 '13 at 06:31
1

That is because the interafce needs a implementation like:

#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion

Because the C# class is abstract it does not (have to) take care of that, and you need to implement it in your C++ class. That is the first class that is not abstract.

  • The abstract class written in C# IS implementing the interface. Doing the same scenario in pure C# (declaring another interface inheriting INotifyPropertyChanged and implementing it on top of the base class) works like a charm... – barnacleboy May 15 '13 at 21:12
  • What I tried to say if that there are two implementations of INotifyPropertyChanged. That is a similar situation as with the public IEnumerator GetEnumerator() and IEnumerable.GetEnumerator() where you need to have both available. – Ferry van den heuvel May 15 '13 at 21:40