edA-qa mort-ora-y
edA-qa mort-ora-y

Reputation: 31871

Share a private implementation between two classes in C#

I'm looking for a way to share the implementation of two classes without exposing any details of that sharing. I was hoping to create this basic class structure:

MyCommonImpl implements the functions of MyInterface and has one abstract function provided in MyImplA and MyImplB. A user of MyImplA should not know about MyCommonImpl in any fashion, it's just an implentation detail.

I've considered doing manual composition, but this involves copying a lot of code to forward the functions. It's also problematic since there are events implemented in MyCommonImpl, and one of their parameters is a sender. This requires putting a proxy handler and partially rewriting events. Basically composition would require more code than simply copy-pasting the entire MyCommonImpl.

How can I do this without having to duplicate a lot of code?

Upvotes: 0

Views: 293

Answers (1)

MarcE
MarcE

Reputation: 3731

You can move the interfaces and implementations to another assembly and mark them internal which will hide the abstract function of MyCommonImpl. Taking it further, you could explicitly implement the interfaces inside that assembly to completely hide their methods from callers leaving only those methods declared public on MyImplA visible.

The internal casts for the explicit implementation are a bit nasty though...

In a separate assembly:

namespace Private
{
    internal interface IMyInterface
    {
        void InterfaceMethod();
    }

    public abstract class MyCommonImpl : IMyInterface
    {
        internal MyCommonImpl()
        {
            // internal ctor to stop callers constructing
        }

        void IMyInterface.InterfaceMethod()
        {
            Console.WriteLine("InterfaceMethod");
        }

        internal abstract void CommonAbstract();
    }

    public class MyImplA : MyCommonImpl
    {
        internal override void CommonAbstract()
        {
            ((IMyInterface)this).InterfaceMethod();
            Console.WriteLine("CommonAbstract");
        }

        public void ImplAMethod()
        {
            CommonAbstract();
            Console.WriteLine("ImplAMethod");
        }
    }
}

Upvotes: 1

Related Questions