Why can't my public class extend an internal class?

C#InheritanceInternal

C# Problem Overview


I really don't get it.

If the base class is abstract and only intended to be used to provide common functionality to public subclasses defined in the assembly, why shouldn't it be declared internal?

I don't want the abstract class to be visible to code outside the assembly. I don't want external code to know about it.

C# Solutions


Solution 1 - C#

UPDATE: This question was the subject of my blog on November 13th of 2012. See it for some more thoughts on this issue. Thanks for the great question!


You're right; it doesn't have to be that way. Other OO languages allow "private inheritance", whereby the fact that D inherits from B can only be taken advantage of by code that has the ability to see B.

This was a design decision of the original C# designers. Unfortunately I am away from my desk right now - I'm taking a couple of days off for the long weekend - so I don't have the language design notes from 1999 in front of me. If I think of it when I get back I'll browse them and see if there is a justification for this decision.

My personal opinion is that inheritance should be used to represent "is a kind of" relationships; that is, inheritance should represent the semantics of the domain being modelled in the language. I try to avoid situations where inheritance is used as a code sharing mechanism. As others have mentioned, it's probably best to prefer composition to inheritance if what you want to represent is "this class shares implementation mechanisms with other classes".

Solution 2 - C#

By inheriting from a class, you expose the functionality of the base class through your child.

Since the child class has higher visibility than its parent, you would be exposing members that would otherwise be protected.

You can't violate the protection level of the parent class by implementing a child with higher visibility.

If the base class is really meant to be used by public child classes, then you need to make the parent public as well.

The other option is to keep your "parent" internal, make it non-abstract, and use it to compose your child classes, and use an Interface to force classes to implement the functionality:

public interface ISomething
{
    void HelloWorld();
}

internal class OldParent : ISomething
{
    public void HelloWorld(){ Console.WriteLine("Hello World!"); }
}

public class OldChild : ISomething
{
    OldParent _oldParent = new OldParent();

    public void HelloWorld() { _oldParent.HelloWorld(); }
}

Solution 3 - C#

I think the closest thing you can do is prevent other assemblies creating the abstract class by making its constructor internal, to quote from MSDN:

> An internal constructor prevents the abstract class from being used as the base class of types that are not in the same assembly as the abstract class.

You can then try adding an EditorBrowsableAttribute to the class to try and hide it from IntelliSense (though, I've had mixed results using it to be honest) or put the base class in a nested namespace, such as MyLibrary.Internals to seperate it from the rest of your classes.

Solution 4 - C#

I think you're mixing concerns here, and C# is to blame, actually (and Java before it).

Inheritance should serve as a categorization mechanism, whereas it's often used for code reuse.

For code reuse it's always been known that composition beats inheritance. The problem with C# is that it gives us such an easy way to inherit:

class MyClass : MyReusedClass { }

But in order to compose, we need to do it by ourselves:

class MyClass {
  MyReusedClass _reused;
  // need to expose all the methods from MyReusedClass and delegate to _reused
}

What's missing is a construct like a trait (pdf), which will bring composition to the same usability level as inheritance.

There's research about traits in C# (pdf), and it would look something like this:

class MyClass {
  uses { MyTrait; }
}

Although I'd like to see another model (that of Perl 6 roles).

UPDATE:

As a side note, the Oxygene language has a feature that lets you delegate all members of an interface to a member property that implements that interface:

type
  MyClass = class(IReusable)
  private
    property Reused : IReusable := new MyReusedClass(); readonly;
      implements public IReusable;
  end;

Here, all interface members of IReusable will be exposed through MyClass and they'll all delegate to the Reused property. There are some problems with this approach, though.

ANOTHER UPDATE:

I've begun implementing this automatic composition concept in C#: take a look at NRoles.

Solution 5 - C#

I think this would violate the Liskov Substitution Principle.

In cases like this, I have used internal classes and prefer composition over inheritance. Is there anything about your design that prohibits containing all such functionality in your internal class, and then have your public classes contain an instance of this internal class?

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDavidView Question on Stackoverflow
Solution 1 - C#Eric LippertView Answer on Stackoverflow
Solution 2 - C#Justin NiessnerView Answer on Stackoverflow
Solution 3 - C#SamuelView Answer on Stackoverflow
Solution 4 - C#JordãoView Answer on Stackoverflow
Solution 5 - C#DaveView Answer on Stackoverflow