Why aren't classes sealed by default? - c#

I was just wondering, since the sealed keyword's existence indicates that it's the class author's decision as to whether other classes are allowed to inherit from it, why aren't classes sealed by default, with some keyword to mark them explicitly as extensible?
I know it's somewhat different, but access modifiers work this way. With the default being restrictive and fuller access only being granted with the insertion of a keyword.
There's a large chance that I haven't thought this through properly, though, so please be humane!

I'd say it was just a mistake. I know many people (including myself) who believe that classes should indeed be sealed by default. There are at least a couple of people in the C# design team in that camp. The pendulum has swung somewhat away from inheritance since C# was first designed. (It has its place, of course, but I find myself using it relatively rarely.)
For what it's worth, that's not the only mistake along the lines of being too close to Java: personally I'd rather Equals and GetHashCode weren't in object, and that you needed specific Monitor instances for locking too...

In my opinion there should be no default syntax, that way you always write explicitly what you want. This forces the coder to understand/think more.
If you want a class to be inheritable then you write
public extensible class MyClass
otherwise
public sealed class MyClass
BTW I think the same should go with access modifiers, disallow default access modifiers.

Inheritance is a foundational principle of OO, so arguably, disallowing it by default wouldn't be intuitive.

You could probably make just as many arguments in favor of sealed-by-default as you could against it. If it were the other way around, someone would be posting the opposite question.

I can't recall having heard a rationale for the decision to have classes not sealed by default. However, there are certainly quite a few people who believe that C# should have been spec'ed to have sealed be the default:
http://codebetter.com/blogs/patricksmacchia/archive/2008/01/05/rambling-on-the-sealed-keyword.aspx

sealed classes prevent inheritance and therefore are an OO abombination. see this rant for details ;-)

80% of the features of Word go unused. 80% of classes don't get inherited from. In both cases, once in a while, someone comes along and wants to use or reuse a feature. Why should the original designer prohibit reuse? Let the reuser decide what they want to reuse.

Merely deriving from an unsealed class doesn't change the class's behavior. The worst that can happen is that a new version of the base class will add a member with the same name as the deriving class (in which case there will just be a compiler warning saying you should use the new or override modifier) or the base class is sealed (which is a design no-no if the class has already been released into the wild). Arbitrary sublassing still complies with the Liskov Substitution Principle.
The reason that members are not overridable by default in C# is that because overriding a method can change the base class's behaviour in a way that the base class's author didn't anticipate. By making it explicitly abstract or virtual, it's saying that the author is aware that that it can change or is otherwise beyond their control and the author should have taken this into account.

For the same reason why objects are not private by default
or
to be consistent with the object analogue, which is objects are not private by default
Just guessing, coz at the end of the day it's a language's design decision and what the creators say is the canon material.

Related

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

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
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.
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.
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?
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.
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

Making abstract classes invisible; or: hiding my BananaHuman

Background: I am still a C# novice and this is my first big project with inheritance. The following story is a simplified example of my current situation:
Suppose I have a class called LivingOrganism. Every living creature can use this class as base and inherit the functionality that is common to all living organisms.
When I was working on some of these derived classes, I found out that bananas and humans are very similar. Although it doesn't make much sense and they look nothing alike, they apparently have most of their "functionality" in common.
Duplication in code is bad, so I wrote a new class to reduce maintenance costs. This class is called: BananaHuman. My Human class and Banana class inherit from BananaHuman.
Problem:
I have no problem with my BananaHuman (i.e. I understand what it means and why it exists). But eventually, other people (even those who don't (fully) understand inheritance) will have to use my LivingCreatures.dll. And they won't understand why intellisense suggests BananaHuman when they type 'B'.
And consider the following piece of code:
//Valid and makes sense.
foreach(LivingOrganism foo in cityOfNeyYork) { /*embedded statement*/ }
But imagine how weird/confusing it would look if we substitute Living Organism with BananaHuman.
I can't make BananaHuman private, protected or protected internal (Elements defined in a namespace cannot be explicitly declared that way). I also can't make it internal, because Human and Banana have to be public. If I try this, I get an error message saying there is an inconsistent accessibility issue.
I feel like I am missing the obvious, but what can/should I do? I am left with a couple of options/questions:
Is it possible to "hide" BananaHuman to avoid confusion?
Should I rewrite BananaHuman to something very long and technical such as DnaRelatedOrganismsType[X], where "X" describes their unique relation?
Should I just delete BananaHuman, let Human and Banana inherit from LivingOrganism and do the extra maintenance when something needs changing?
Is there another solution I am completely missing?
I searched around and couldn't quite find a "fixed pattern" for this situation. I found this question with a similar title, but I don't know if the answers are applicable because it appears that he is asking something completely different.
Any help is greatly appreciated!
You can use the EditorBrowsableAttribute and apply it to your class. This will make you class disappear from Intellisense if people are using your .dll. If you have your project referenced instead of the dll it will still be visible.
Use like:
[EditorBrowsable(EditorBrowsableState.Never)]
public class BananaHuman
{
//....
}
So if you would give me your .dll I wouldn't see BananaHuman pop up in Intellisense. But if I would inspect the Banana or Human class I would still see it inherited from BananaHuman because that IS the case. The EditorBrowsable attribute just makes it disappear from Intellisense, what is what you want.
The existing answer is a great technical solution to the specific problem of hiding the BananaHuman from intellisense. But since the OP also asks about changing the design, I think it's also within the scope of the question to give a quick answer about why the existence of BananaHuman is a code smell and it should probably be a candidate for refactoring.
You may have heard of the SOLID acronym for five important design principles. BananaHuman runs counter to two of them: the Single Responsibility Principle (SRP) and the Open/Closed Principle (OCP).
Bananas and humans may share a lot of DNA, but just like code, they should also be expected to evolve, and probably evolve separately from each other. That same DNA may not always be exactly shared. The SRP states that a class should only have one responsibility or- equivilently- should only have one reason to change. But BananaHuman will always automatically have at least two possible reasons to change- a change in the specifications for Banana or a change in specifications for Human.
Why is this the case specifically for BananaHuman, but not for all general base classes? Because a base class should represent one single well-defined concept, just like any other class. So for example Mammal would only have to change if the features making up the concept of a mammal change. If one particular mammal evolved to lose its hair, it's that animal's class that would change, not the base Mammal class. BananaHuman, on the other hand, is by definition "the features common to both a banana and a human", so it will always be coupled to at least two rather than one concepts. Likewise, there may be several things in common between a banana and a human which don't have much else to do with each other. Shoving these all into a single class reduces cohesion and piles more responsibilities into one place.
The OCP states that a software entity (such as an interface, class or method) should be open to extension but closed to modification when requirements are added or change. For example if you added another living organism sharing the same traits as Banana and Human, you'd have to change the name. Or if it only shared some of the traits, you'd have to shuffle around the base classes, potentially even running into multiple inheritance problems if this came up multiple times. I'm sure there are plenty of other situations which would lead to OCP violations too.
So what should you do?
Well, if you read the above and thought that the characterization of BananaHuman was unfair, and that actually it does map to a very well defined concept just like Mammal does then... rename it to what it actually is! That's all you need to do, and you're probably good to go. It doesn't matter if the name is long (though ideally concise is better, and you should make sure length doesn't indicate you're jamming multiple things together into one series of words).
If that's not the answer, then look into the idea of composition over inheritance. For example, if you have multiple living organisms which all have lungs, instead of creating a LivingOrganismWithLungs class, create a Lungs class, and have every living organism with lungs contain an instance. If you can separate out the common features into their own classes like this then you have a much nicer solution.
If those are both really not possible (rare, but it can happen) then BananaHuman may be the best option left. It would have to be up to your judgement to evaluate the SRP and OCP problems versus the Don't Repeat Yourself (DRY) violation.

Is it possible to have over inheritance to be lost in code?

I'm currently working on an asp.net site, done by someone else, and it's rediculously over complicated for what it does......Well I think so! Pretty much every class inherits from another class then another and another and so on and on....... You have to go about 8/10 levels on average to get the the base class, sometimes more! And these classes have other classes inside which follow the same pattern of Uber Inheritence.
This leaves me lost in code many many times resulting in God knows how many tabs open on visual studio.
Is this good/normal practice or is it bad practice? I feel it's bad practice as something so simple is made over complicated with an over usage of inheritance resulting in un-extensible code...............but I could be wrong :)
Thanks!
Yes, over-using inheritance can lead to a spaghetti warehouse. Inheritance is a tool to allow for encapsulation and abstraction. Abusing it causes too much abstraction and then the purpose of the code becomes unusable. I've seen this pattern abused in imperative constructs as well where a method is passed from method to method to method before an action is actually applied.
private bool getData()
{
return getOtherData();
}
private bool getOtherData()
{
return getSomeExtraData();
}
private bool getSomeExtraData()
{
return SeeHowTediousThisIs();
}
It all works, but it's just an exceptionally bad architecture for maintenance. I find this often occurs with consultants/contractors attempting to introduce complexity (re: job security).
There is a design guideline of 'favour composition over inheritance' 8-10 levels on inheritance breaks that somewhat.
http://en.wikipedia.org/wiki/Composition_over_inheritance
Inheritance as a means to reusing code is a pretty bad choice indeed. Consider that every class in .NET-based languages have a single slot of inheritance where code can go. Hence, for each class it should be chosen wisely whether it should inherit from something else or not.
Classically one says that inheritance describes a "is-a" relationship, where by going up the inheritance chain we reach higher levels of abstraction.
The first question should always be whether a "can-act-as" relationship isn't sufficient. In this case, describing the relationship via interfaces is often a better choice. Secondly, when adding abstractions, the question must be whether a non-negligible amount of code can work with those abstractions in order to satisfy the features you are seeking.
If there is hardly any code using those abstractions, then they are most likely worthless by themselves. Again, the cost of abstraction is usually lower with interfaces than with base classes.
So, in summary
A "can-act-as" relationship is usually enough - You then don't need to go for a "is-a" relationship
The inheritance slot is precious - It can be used only once.
There are many more ways for code reuse than inheriting from a class
Base classes and interfaces are abstractions: Make sure that your code can indeed make use of them. If your interface is implemented by only one class, your abstraction is possibly worthless and easily introduced when it becomes necessary.
If there is a need for abstraction, the penalty is lower on interfaces than on base classes.
Sounds like inheritance-overkill, very rarely should need to go beyond 2-3 levels, and that would be for a complex business model.
What sort of classes are these? Controls? Business Objects? Are they documented (UML) anywhere so that you can get a good overview of the model?
8-10 levels deep is a lot, I would hazard a guess that these classes were coded before (or never) designed.
Most certainly I've been digging through inheritance hell lately. we quite literally have code that looks like this
Public Class A
' Do Stuff, methods, members, etc.
Public var As Object
Public Sub New()
member = New Object
End Sub
End Class
' yes it's empty
Public Class B : Inherits A
End Class
' yes it's empty
Public Class C : Inherits A
Public Sub New()
MyBase.New()
member.SomeMethod()
End Sub
End Class
Then there's the Base class that contains a list of objects that MUST be inherited in order to add objects to that list.
In short, yes inheritance can most certainly be abused, just like everything. Most help for me was to find a good UML modeling tool that will reverse engineer the language you're using.

When defining a class as internal, do you define what would usually be public fields as internal?

When defining a class as internal, do you define what would usually be public fields as internal? Or do you leave them as public? I have a set of classes with public/private methods that I have decided to set as internal. Now, should I change the class' modifier to internal and let the rest of the methods/properties as they are (public/private) or switch them to (internal/private)?
I don't see a big point in changing it to internal, and if by some reason later I want to set them back to public it's going to give a lot of work to have to put them back to public again.
Any other thoughts on this?
I can't see any reason not to leave them as public, as your class won't be visible to outside assemblies anyway. The only case where I think this might matter is when using reflection over that class.
If I have a class that is internal, I leave the class members as public (or protected/private of course if that's what they were). I find that often I have classes that I hope I can keep internal that I end up having to expose eventually and switching all the appropriate members back to public is annoying.
You defnitely shouldn't change private members to internal as that would make them more accessible. There is no need to change public members to internal since nothing outside of the defining assembly will ever be able to get a reference to an internal class anyway.
I think you should give generally members the same visibility as you would if the Type were itself public.
That is, members that are part of the public API should be public, and members that are special-purpose helpers that should only be visible to "friend" classes should be internal.
This means there will be no changes to member visibility if you ever decide to make the Type public.
More importantly, it also documents your intention - anyone reading your code will be able to identify which (if any) members are intended to be internal.
We use internal keyword for members in internal classes, so that the intention is clear. However it fails if one implicitly implement internal interfaces, where the members have to be defined as public. We dont know why and see this as an accidental mistake in the language specification that we have to live with.
Dig around in Reflector for a bit and you'll see that the BCL itself is wildly inconsistent over this. You'll see many internal classes with public members and many others with internal members. Several classes even mix and match the two with no particular rhyme or reason that I'm able to discern.
There is no "right" answer here, but there are a few things you should consider whenever you need to make a decision on this:
internal members cannot implicitly implement an interface, and explicit implementations are always private. So if you want interface members to be accessible through the class instance (the Dispose method of IDisposable is a common one), they need to be public.
Type visibilities can change. You might decide down the road that an internal class has some valuable functionality that you want to make available to the outside. But if you do, then all public members become accessible by everyone. You should decide in advance if this is what you want.
On the other hand, another reason you might make an internal class public is if you decide that you need to subclass it and that the derived classes should be in a different assembly. In this case, some of your internal members should probably be protected internal instead, otherwise derived classes won't have access to members they might need.
In the end, what it all comes down to is writing code to be read and maintained by other people. The modifier internal can mean two very different things to a maintenance programmer:
That it doesn't seem useful to the outside world, but wouldn't actually be harmful either. A typical example would be a utility class that was whipped up in 5 minutes and doesn't do much validation or error checking. In this case, it's OK for someone to make it public as long as they tighten up the code a little and/or document how to use it properly. Make this assumption explicit by making the members public.
That it's actually not safe for outside consumption; it might manipulate some protected state, leave handles or transactions open, etc. In this case, you really want to make the individual methods internal to make it absolutely clear that nobody else should be using this class, ever.
Choose whichever one is appropriate for your scenario.

Overriding a read/write property to make it readonly

I'm writing a custom control in C# based on TextBox. I want the Text property of my control to be read-only (since only certain values are allowed in the textbox and I don't want the calling program to be able to put invalid values in there.)
I don't see how to do this. If I use public override Text {} the compiler inserts default get and set accessors. If I comment out the set accessor, the code compiles and runs, which I assume means the base accessor is being used. If I put readonly in the definition of my property, the compiler throws an error.
Any help would be greatly appreciated.
The issue here is that by trying to make a read/write property read-only, you're violating the contract of your base class. Your base class explicitly states that this property can be both retrieved and modified. Derived classes cannot break the contracts of their base classes, otherwise polymorphism would fail. Remember that if B derives from A, anywhere an A object is accepted, B must perform.
If that should not be the case for the derived class, then I would first question the design -- should this truly be derived from the base class? Is this truly an "is-a" relationship?
Assuming that we passed that test and truly should be derived, one approach -- which I don't personally like, but will share anyway -- may be to simply have the setter throw an exception. I personally don't like this, it still violates the contract, and feels like an excessive amount of cognitive friction in using your derived class, but if you truly have that solid a reason to do so ... well ... OK, I guess. But be sure you know WHY you're hacking around this.
But go back to the first point: Is this truly a scenario where a derived class is the right answer, from a design standpoint? Without seeing your code, my gut reaction is a no.
EDIT
Somehow in my initial read of this, I missed the fact that we're talking about a UI control here. I stand by what I wrote above this edit, in the general property overriding case. However, in the case of a UI control, where the polymorphism opportunities (I hope) will be somewhat limited, and where the need may well justify this design, then my recommendation would be to have the Text property setter throw an exception.
A better design, in my opinion, would be composition. Make a user control, add the TextBox to the user control design surface with Dock=Fill, and then expose a new Text property which is readonly. You can also now expose only those properties you really want to.
You have to hide the base property by declaring Text with the "new" keyword.
public new string Text { get; private set;}
You can't change access rights with an override, so you cannot use the override keyword, as you've seen. This way will "hide" the base implementation of Text, which isn't always a good idea, but as long as you know the risks it will work for you.
public new string Text { get; private set;}
Aside from others comments on overall design issues (which John Ruby explains nicely), you could always just override the setter to do nothing or throw an exception.
I don't think that shadowing the property is the right answer, because any reference through the base will still work. Since the property is virtual, you can override it and implement a setter that ignores changes or throws an exception. I know it seems less clean, but it has the advantage of actually working.
edit
Looks like Yuriy Faktorovich made the same suggestion before I could.
I think John Rudy may have a point here. Inheritance is not the answer to everything. If what you need to do is restrict a textbox so that only valid values can be accepted then perhaps you want to use a validation control to make sure that only certain values are allowed.
This way you get the behaviour you want by making use of the components Microsoft have provided us with. No inherited class necessary.
Edit: If you create a subclass every time you want to modify the behaviour of a UI control you will quickly have an unruly inheritance hierarchy on your hands. For this reason I would suggest you consider composition to modify UI controls.

Categories

Resources