Summary
Eric Gunnerson, the C# Compiler Program Manager at Microsoft, talks with Bruce Eckel and Bill Venners about
several architectural design decisions in .NET, including multiple inheritance of interface, the emphasis
on messaging over mobile code, internal access in assemblies, and the side-by-side execution answer
to DLL Hell.

Eric Gunnerson, after having
previously worked at a large Seattle aerospace company, a medium-sized PC database
company, and a small VMS utility software company, joined Microsoft in the fall of 1994.
After several years working on Microsoft's C++ compiler quality assurance team, including three years as the test lead on
the Visual C++ compiler, Gunnerson took on a new assignment: testing
the compiler of Microsoft's new language, C#. To more effectively perform his quality assurance role, Gunnerson
joined the C# design team, where he spent several years working with Anders Hejslberg,
Peter Golde, Scott Wiltamuth, Peter Solich, and Todd Proebsting on the design of C#. In 2002, after the
initial release of Visual Studio.NET, Gunnerson switched from quality assurance to program management.
He is currently the C# Compiler
Program Manager. He is author of A
Programmer's Introduction to C# (APress, 2001), and writes a column for MSDN, Working with C#.

On July 30, 2003, Bruce Eckel, author of Thinking in C++ and Thinking in Java, and Bill
Venners, editor-in-chief of Artima.com, met with Eric Gunnerson at Microsoft in Redmond,
Washington. In this interview, Gunnerson discusses several architectural design decisions in .NET,
including multiple inheritance of interface, the emphasis
on messaging over mobile code, internal access in assemblies, and the side-by-side execution answer
to DLL Hell. Comments are also contributed by Dan Fernandez, Microsoft's Product
Manager for C#.

Multiple Inheritance of Interface Only

Bill Venners: The CLS, the Common Language Specification, has
single inheritance of implementation, multiple inheritance of interface.
Could you explain what the CLS is, and how the inheritance model was
was decided upon?

Eric Gunnerson: The CLS describes how languages should behave so they can play
nicely together. For example, C# has unsigned types, but unsigned types are not in the CLS
because languages like VB [Visual Basic] can't handle them. I think of the CLS as an interoperability
spec. If you adhere to the CLS, then you can interoperate with the other languages.

Multiple inheritance has two or three big issues. First, trying to get
people to agree what multiple inheritance actually means is difficult. If we try to do multiple
inheritance in the CLS, we would probably choose something along the lines of multiple
inheritance in C++, and that would put languages that have other kinds of multiple
inheritance in an ugly state. People would say, "Microsoft supports multiple inheritance, but
they support it wrong. I can't make my language work using what they have." People would
make that argument.

A second issue for me is just the cognitive complexity involved—what it takes to
understand what is really going on in your code when you start using multiple inheritance. I
think multiple inheritance is kind of like the advanced operator overloading in that respect.
To really understand what's going on you have to think deeply. It may not hit you in a lot of
cases, but there may be cases where something works strangely and you have to dig deeply to
understand it. You should tend away from that kind of complexity when you are doing object
design.

Now obviously one other question is, given that we're multi-language, what would you do with
languages that don't support multiple inheritance? I don't see how we could ever put multiple
inheritance in the CLS.

Bruce Eckel: What do you do with managed C++? Does it have multiple inheritance?

Bruce Eckel: I see, if I want a VB program to use this C++ class, I don't
use multiple inheritance.

Eric Gunnerson: Another problem with supporting multiple inheritance is that if you
were designing with multiple inheritance, you would do class libraries differently than you
would with our current system. But then you can't do that, because some languages don't
support multiple inheritance. So you might bifurcate the libraries—have one way for
the multiple inheritance languages and one way for the other languages. But that would make
the libraries very hard to understand.

Don't Burn Your Base Class

Bruce Eckel: Does the CLS allow multiple interface inheritance?

Eric Gunnerson: Yes.

Bruce Eckel: But that's a reasonable constraint.

Eric Gunnerson: It's a reasonable constraint if nobody causes you to do anything that
makes you burn your base class.

Bill Venners: Burn my base class?

Eric Gunnerson: I'll give you the canonical example. When you want to make a
component a remote object, you must derive its class from a base class called
MarshalByRef. When MarshalByRef subclasses get marshaled,
they get marshaled by reference. You get an object over here and a proxy over there, and the
runtime handles all the mechanics. That works great, unless you actually want to use
inheritance in your design. Because the designers of remoting decided to do this with the base
class, they took the option of using inheritance in any other way away from you. They
burned the base class.

Bill Venners: They burned the base class because if I want to remote something, I
have to extend their class, not some other class I may want to extend.

Eric Gunnerson: Maybe you can get away with extending a class of yours that extends
their class.

Bill Venners: But if it doesn't already extend their class and I can't change it, then I'm
out of luck.

Eric Gunnerson: Yes, exactly. The constraint in supporting single inheritance of
implementation, multiple inheritance of interface is that you have to pay a lot of attention
about what you do. In fact if you go talk to customers that use remoting they say that exact
same thing, why are you burning a base class here? You don't need to. You could use attributes
or some other mechanism.

Bill Venners: So in design you should be careful not to burn your base class.

Eric Gunnerson: Yes. In design you have to be very careful.

Now, just because the CLS only directly supports multiple inheritance of interface doesn't
mean that individual languages can't support more. Eiffel on .NET has multiple inheritance,
for example. When compiled, it uses multiple interface inheritance and creates classes under
the covers as necessary. So they do support full multiple inheritance, because Eiffel without
multiple inheritance is way worse than C++ without multiple inheritance. A lot of common
Eiffel idioms require multiple inheritance. It's just the way you write Eiffel code.