tags:

views:

34

answers:

1

I am writing two C++/CLI assemblies. One assembly has a base class with some internal virtual methods. The other assembly is marked as friend and contains derived class.

When I try to override the internal virtual method, the compiler is forcing me to change the visibility level to public.

What is going on? Why do I have to do this?

Code:

// Assembly 1 "FriendAssemblyBase"
namespace FriendAssemblyTest
{
    public ref class BaseClass
    {
    internal:
        BaseClass()
        {
        }

        virtual void DoSomething()
        {
        }
    };
}

// Allow "FriendAsseblyDerived" to see internals
[assembly:  ::System::Runtime::CompilerServices::InternalsVisibleToAttribute(
"FriendAssemblyDerived, PublicKey=0024000004800000940000000602000000240000525341310004000001000100a95fe809ecc53c3a826aa32e3ab1309f2ecae4b91dc649457d704e150f3a4007a151ffe28852f947803dd1a1586c5c0ae2c9688bd76299857ee65ff7efb14905e03b33664a42e2fa1074080c3bad971623514ab6dd9fc4e4343ba7fb98884ecce45f96b71e5f1b55de88e36483274aa71c740fdfb14aacaada6ca22cb39bf9a2")];

// ----------------
// Assembly 2. "FriendAssemblyDerived". Strongly named and signed
#using "FriendAssemblyBase.dll" as_friend
namespace FriendAssemblyTest
{

    public ref class Derived : BaseClass
    {
    public:
        Derived() {}

        void Foo()
        {
            DoSomething();
        }

    internal: // <-- Causes C3252 (cannot reduce visibility of virtuals)
        virtual void DoSomething() override
        {
        }
    };
}
A: 

Because other classes in FriendAssemblyBase can call BaseClass.DoSomething.

the Liskov Substitution Principle says that anything that can be done with the base class must be doable with every derived class. Do DerivedClass.DoSomething has to be visible to FriendAssemblyBase. The only way that can happen is with public:.

Ben Voigt
But can't it just call its own virtual function? How is this different than protected visibility?
Filip
**Other** classes in `FriendAssemblyBase`, not necessarily `BaseClass` itself, can call the function. That wouldn't be true for protected.
Ben Voigt
Got it. Makes sense.
Filip