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.