|
![](/i/fill.gif) |
On 08/08/2012 09:41 PM, Orchid Win7 v1 wrote:
> Apparently I need to learn C# then.
So today, I decided to take a look at that. So far, I've been variously
amused and horrified.
"C# programs run on the .NET Framework, an integral component of
Windows"
It tickles me that by "integral component of Windows", what they
/actually/ means is "quarter of a gigabyte optional download". :-P
(Not only is it a quarter of a gigabyte - which, even with 5mbit
broadband, takes quite a while to download - but it also takes about 35
minutes to actually install the thing! And that's not counting the
further 15 minutes where the ".NET optimisation service" is silently
running in the background without telling you, slowing your PC down
until you let it finish...)
Then we start to get into some of the design decisions.
First of all, C# does that Java thing where it doesn't actually support
multiple inheritance (because that's too complicated), but it /does/
support interfaces. *sigh*
Oh, but we still get much of the complexity of MI, Eiffel-style. For
those of you who've never /heard/ of Eiffel, it's essentially the
ultimate multiple-inheritance object-oriented language. The designers
took all the ideas of OO to their logical extreme, resulting in a very
rigorous but quite complicated language. It does things like allow
subclasses to rename inherited methods, but anyone calling through the
superclass interface still gets the old names. Because when you have
multiple superclasses, you might inherit two methods with clashing
names, and you need to sort that out. Add generics, and it gets
complicated fast.
C# doesn't allow MI, but it does attempt to stop changes to a superclass
breaking all its subclasses. The idea being that company X changes their
superclass to add a new method, who's name now clashes with a method
defined in a subclass written by company Y. And the runtime supposedly
sorts out all the same-name madness for you.
Arguably the only /good/ thing to come out of all of this is that if you
/meant/ to override an inherited method, you have to explicitly /say/ so.
OTOH, C# does that thing that C++ does where it's impossible to override
a method, unless you manually declare it as "virtual". This violates one
of the ideas behind OO, which is that if you've got a class that does
nearly what you want, but not quite, you can subclass it and change it
to make it do what you want. Well, no you can't, not if some of its
methods can't be overridden.
It's true that having non-virtual methods introduces a tiny performance
benefit. It's true that inheritance is over-used anyway, and you can
usually get the same effect or better using collaboration instead. But
still, the objection stands.
And then we get into access specifications. Java has public, private,
protected and package-local (which is implicit, and cannot be written
explicitly). C++ has... well, I'm not even sure /what/ the hell C++ has!
And C# has the whole cake shop.
Not only can you declare the accessibility of a thing, but there are
restrictions on what you can do. A subclass can't make stuff more secret
than its superclass (because clients might be using that interface
instead). You can't make something public if it refers to private types.
And so on.
As I sit here and listen to all these complicated rules about what can
and can't be public and the convoluted rules for resolving a method call
to an actual block of code, I can't help thinking... Did you guys ever
thing that maybe if it ends up being this complicated, you're doing it
wrong?
People have criticised OOP for being ad hoc and lacking a coherent
theoretical foundation many times, of course. There was a time (around
about 1998 or so) when I thought that OOP was the ultimate answer to
every possible coding problem, and it was the way of the future. Today,
it just looks overly complex and ill thought out. Especially when
looking at something like C#.
Still, not liking C# isn't going to change the fact that it is
(apparently) the most popular programming language now... :-P
Post a reply to this message
|
![](/i/fill.gif) |