Fyi... this stackoverflow Q&A has opinions on why 'sealed' is a rational default for the person who designed the class: https://stackoverflow.com/questions/268251/why-seal-a-class/
It doesn't mean the programmer thinks the base class is "perfect". Instead, the author has not deliberately designed the particular class for inheritance and the "sealed" keyword expresses that.
Looks like my issue with that got fixed with extension methods, which should let me tack on such improvements whether the original designer of the class thought that would be a good idea or not.
That was something I was recalling from a very old project though. I'm not sure right now when that was exactly. Maybe it wasn't in the language yet at the time, or was a new feature still and I didn't find about it, or it wasn't in Mono yet.
I've not done C# in a long time, so no doubt I missed a lot of developments.
Just... exactly this. Hate that so much. I cannot articulate how much I agree with what you have said here.
This issue might not seem relevant in your own projects, where maybe you want to seal a class so a junior developer doesn't break something.
But it's disastrous for library and framework development. Here's an open question of mine related to this:
https://stackoverflow.com/questions/65852139/listen-for-chan...
In that case, I'm trying to write a script that people can attach to a game object to rebuild metadata after a mesh is changed. I need the metadata for my shader, since it needs info about neighboring vertices, which would only be available in geometry shaders (which have fallen out of fashion since they run at the wrong stage of the rendering pipeline).
That way my shader would "just work" without making the user have to remember to set a flag or send an event when something changes (which is not future-proof).
Normally I would just inherit from the Mesh class, override/extend methods like Mesh.SetVertices(), and then explain how to use my class in the readme. Better yet, I would use something like inversion of control (IOC) to replace the project's global Mesh class with my own (this is how frameworks like Laravel work, or try to work). In fact, there are half a dozen ways of accomplishing this, perhaps more.
But with sealed and final, I'm just done. There is no workaround, by design. Because C# inherited this kind of opinionated thinking (anti-pattern) from Java. And Unity uses C#, so unwittingly fell into this trap since so many of their classes are sealed. Which all reduces languages like C# and Java to being toy languages, at least for someone like me working from first principles under some approximation of computer science.
Maybe I should write to Unity and explain that all of this happened during the very first interesting thing I tried to do. Or maybe we could get rid of this concept altogether and avoid the problem in the first place.
Even the gospel of Martin Fowler tends to agree with my stance on this:
Eg, in C#, SqlDataReader is sealed. Which means I have to do this:
When I just want to skip the verbosity and be able to do this: So the logical thought there would be just to inherit from it, add an extra overload to those functions, and life got more comfortable, plus you can still pass it to anything that wants a SqlDataReader. But oops, you can't do that, because somebody at Microsoft decided the interface for this thing was perfect is not to be messed with.If there's something that really gets me annoyed is when I run into a limitation that seem completely arbitrary but intentional. It's not there because of the technical limits of the hardware, or because the compiler isn't clever enough, but purely because somebody intentionally decided 'nope, you don't get to do this particular thing you can do all day otherwise'.