Search code examples
c#.netoopfluent

Member can't be protected if used "fluently", even though it shouldn't be used outside


I have the following example:

class A {
    public A DoSomethingInternal() {
        // Some work..
        return this;
    }
}

class B : A {
    public void DoSomething() {
        DoSomethingInternal().DoSomethingInternal().DoSomethingInternal();
    }
}

DoSomethingInternal is a method that should not be called by the outside objects. It should only be accessible to A and the inheritors of A - so it sounds like it should be protected. However, due to the fact that DoSomethingInternal is a "fluent" method, I cannot make it protected.

A solution that I see is:

class A {
    public A DoSomethingInternal() {
        // Some work..
        return this;
    }
}

class B : A {
    public void DoSomething() {
        ((B)(((B)DoSomethingInternal()).DoSomethingInternal())).DoSomethingInternal();
    }
}

but I find it very inelegant to require derived classes to do these casts.


Solution

  • You can "tell" base class about derived class as a generic type argument.

    public abstract class A<T> where T : A<T>
    {
        protected T DoSomethingInternal()
        {
            // Do something
    
            return (T)this;
        }
    }
    
    public class B : A<B>
    {
        public void DoSomething()
        {
            // Do something
            this.DoSomethingInternal().DoSomethingInternal();
        }
    }