That's easy - anywhere .Net defines my inheritence tree becomes a good
case.
Let's say I have a business Entity called "User Roster".
Let's say I want to build a .Net Windows Forms control called "User
Roster". This control MUST inherit from "control", I've got no choice
about it. This means I'm stuck encapsulating a "Business.UserRoster"
inside my control, and exposing everything I want manually. If I want to
be able to pass my roster back down into the business layer for
processing, I can't pass this class - I need to pass the encapsulated
class.
If I had multiple inheritence, I could be both "A control" and "A User
Roster". This means I didn't have to write ANY extra code, and I can pass
my control around, and down into the business layer for processing as a
Roster. Very handy.
The thing hold true for any Enterprise Services work: Anything I want to
be serviced MUST inherit from "ServicedComponent". This means if I want to
stick alot of Business.UserRoster classes into COM, I can't use
inheritence. MI solves this problem nicely.
At a more classic level, the bowels of our SDK have alot of code for
stream and socket manipulation. We have classes such as
"XMLStreamReceiver" "XMLStreamSender", and then classes that manually
stitch these two together into a bidirectional stream. We've got
"XMPPSocket" which manually aggrigates a number of different stream
types - an xml stream (for stanzas), encrypted data, compressed data,
binary data, etc. Multiple Inheritence would have eliminated hundreds
(thousands?) of lines of this code.
We've got many classes that interact with our Trace Infrastructure. We
solved this by having a [Tracable] attribute, and some aggrigated code in
each traceable class. It would have been MUCH easier to have trace as a
pure aspect, and each class that was traceable just inherit from the
Traceable class. Lots of code would disappear.
We've got a few hundred custom performance counters, all stemming from our
"SafePerformanceCounter" class. Any class that wants to use these, is
stuck declaring them member variables, and writing a fair bit of code to
tickle the things at the right times. Multiple inheritence could have
easily solves this with an "inherits InstrumentedClass" case, and, again,
many, many, many lines of code would disappear.
In our server, we have handlers setup to handle different types of data
that come in. These handlers (by design) are required to inherit from our
"PacketHandlerBase" class. This means any handler that want to do custom
stuff, has to aggrigate that custom stuff. So, for example, if we want to
Packet Handling class to act like a stream (so it can be exposed to the
huge stream processing infrastructure that we have), there's alot of
custom code that need be written.
All of these can be (indeed, have been) worked around - but it's a clumsy
workaround, where MI would have provided a much more elegant solution.