What is the origin of CS0060:The direct base class of a class type must be at least as accessible as the class type itself

1.7k Views Asked by At

I just ran into this basic rule about inheritance in .net:
CS0060:The direct base class of a class type must be at least as accessible as the class type itself

I'm curious why this rule was developed.

Does anyone know why this kind of inheritance is preferred? Are there any languages that do it differently.


    // CS0060.cs
class MyClass
// try the following line instead
// public class MyClass
{
}

public class MyClass2 : MyClass   // CS0060
{
   public static void Main()
   {
   }
}

Thanks

5

There are 5 best solutions below

2
On

I'm curious why this rule was developed. Does anyone know why this kind of inheritance is preferred? Are there any languages that do it differently?

The second question is much easier to answer than the first. Yes, other languages do it differently. In particular, C++ allows "private inheritance"; that is, the inheritance relationship becomes a private implementation detail of the class. If C# had private inheritance then clearly the base class could be less accessible than the derived class. But C# does not have private inheritance.

The first question is difficult to answer because "why" questions are inherently a bad fit for Stack Overflow. The only correct answer to "why was this rule developed?" is "because the language design committee decided that this was the best compromise when given many competing design goals".

That's probably not a satisfying answer. To answer this question properly would involve not just listing all of those design goals and their relative merits, but also describing the mental state of each member of the design team at the time the decision was made, and also describing by what process the various conflicts that arose were resolved. This decision was made thirteen years ago, so that trail is very cold indeed.

I was not in that room on that day thirteen years ago but I can give you some idea of the factors that the design committee would have considered when deciding whether to allow private inheritance:

  • Impact on "concept count". (How many related concepts does the user have to understand in order to use the feature correctly? How many new concepts does the feature add to the language?)
  • Similarity or dissimilarity of the feature to C++, which could be either helpful or confusing.
  • Success of the feature in C++. Do people use it in C++? Do they use it correctly? Does every C++ user understand this feature well enough to make a good choice?
  • Amount of interaction with other language features. Such a feature would change name lookup and overload resolution in potentially subtle or confusing ways.
  • Level of consistency with related language features. (Interfaces are allowed to be less accessible.)
  • Difficulty of implementation.
  • And many more factors.

Since I don't have the three or four hours to spare that it would take me to write up a detailed analysis of all those factors for this feature, and then try to retroactively psychoanalyze the design team, I think you're going to have to live with your curiosity unfulfilled.

I recommend against asking questions like this on StackOverflow in the future. Try to stick to specific technical questions about actual code that have precise answers.

0
On
class BaseClass {...}
public class MyClass: BaseClass {...} // Error

http://msdn.microsoft.com/en-us/library/cx03xt0t.aspx

This is mentioned in the C# language specification and also this makes perfect sense because in your case the public class can be used in "public" context with public accessibility level allowing the access of a non-public class which is your base class and this would be the wrong behaviour.

According to C# Language Specification 5.0:

(Download the spec from http://www.microsoft.com/en-us/download/details.aspx?id=7029)

The following accessibility constraints exist:

The direct base class of a class type must be at least as accessible as the class type itself.

• The explicit base interfaces of an interface type must be at least as accessible as the interface type itself.

• The return type and parameter types of a delegate type must be at least as accessible as the delegate type itself.

• The type of a constant must be at least as accessible as the constant itself.

• The type of a field must be at least as accessible as the field itself.

• The return type and parameter types of a method must be at least as accessible as the method itself.

• The type of a property must be at least as accessible as the property itself.

• The type of an event must be at least as accessible as the event itself.

• The type and parameter types of an indexer must be at least as accessible as the indexer itself.

• The return type and parameter types of an operator must be at least as accessible as the operator itself.

• The parameter types of an instance constructor must be at least as accessible as the instance constructor itself.

1
On

All subsequent classes must have at least the same accessibility as the MyClass2 in your example.

This is logical, hence the following example.

When you have a internal class A with a public property called Prop. How do you think the outside world would know your derived public class B has a property Prop if the base class isn't public also?

1
On

I see your point, @mohammed sameeh. What is the value of this? Or what would be the side effects if .net behaved differently, if it tried to allow this?

@Anirudh was getting to that, when he talked about the security of that base class.

If you didn't have this restriction, the security model of consistently hiding "private"/"internal" things could be broken - or else very confusing!
That's really the biggest potential side effect, wrongly exposing properties and methods.

Since the child class, by definition, inherits the parent's properties & methods, how should they be considered in this case?
Rather than having (even more) rules about how properties & methods are exposed in inheritance and subclassing, .net simplifies things by maintaining a hierarchy of exposure and enforcing it.

Someone else might have a cool point to make about what would happen to type casts or the like without the restriction.

Certainly other rules could exist. It might be interesting to see another language that does it differently.

But for sure we want some kind of rules, so when someone else consumes your class or assembly, you know what to expect.

0
On
class MyClass

{
}

public class MyClass2 : MyClass   // CS0060
{
   public static void Main()
   {
   }
}

the causes of this error is beacuse the MyClass is not public so you need it put public just add public before class MyClass