Why can't an interface contain types?

Why can't an interface contain types?

Before digging into the question let me clear up a couple of things.

First, the CLR type system does permit nested types inside interfaces. It would be entirely possible to create a version of C# or VB or whatever tomorrow that supported interfaces, delegates, classes, structs and enums to be declared inside interfaces, and it would run on the existing CLR.

Second, I will give you my usual pushback on questions of the form "why does the C# language not implement feature X?" The answer is the same for all values of X. In order to be implemented a feature must be: thought of, designed, specified, implemented, tested and shipped to customers. If any one of those six things does not happen then there is no feature. Feature X is not implemented because one or more of those things did not happen.

Third, the C# compiler team (which I am no longer on) does not have to provide any explanation for not implementing a feature. Features cost money, the budget is finite, and therefore the onus is on the person requesting the feature to justify its benefits against its costs.

Fourth, "why" questions are hard to answer and "why not" questions are even harder.

So, with that said, I'll reject your question and replace it with a question I can answer:

Suppose this feature request had been proposed to the C# design team. What arguments would you have made against it?

  • The feature, though legal in the CLR, is not legal in the CLS. There are lots of features in C# that are not legal in the CLS, but since the CLS guidance is specifically do not nest types in interfaces because most languages do not support it, implementing the feature in C# is essentially encouraging people to write libraries that cannot be used in other languages. The proposed feature encourages a bad programming practice.

  • Nested types give you three main advantages. First, they have access to the private members of their enclosing types. This is not a benefit for interfaces, which have no private members. Second, they provide a convenient way to contain a specific private implementation detail of the outer type. This is not a benefit for interfaces, which presumably could not have a private nested type, and which do not have implementation details by definition. Third, they provide a convenient way to associate one type with another; however, this is better done by namespaces.

  • No one else to my knowledge is requesting the feature. Let's not spend money on a feature that hardly anyone wants when there are plenty of features that customers do want.

  • Implementing the feature doesn't make the language more powerful or more expressive in any way in of itself.

  • Implementing the feature is not a stepping-stone to some more awesome feature that I am aware of. The feature doesn't tie into any other "theme". It's a "completionist" feature that eliminates a small non-orthogonality, not a useful feature.

  • There exists an easy workaround for the lack of the feature; just make the nested type a top-level type.

That's the case against. Without someone to advance a case for the feature, it's not going to last in the design committee meeting for more than maybe five minutes tops. Do you care to advance a case for the feature?


Would like to add, that from C# 8.0, interface is permitted to use nested types.

Default interface methods - C# 8.0 specification proposals | Microsoft Docs (emphasis added)

The syntax for an interface is extended to permit:

  • member declarations that declare constants, operators, static constructors, and nested types;

So something like below is now legal.

interface ISpectrum {
    [Flags]
    enum Palette { Red = 1, Green = 2, Blue = 4 }
    Palette Color { get; }
}

Whether this is good practice has been discussed in other answers, but I personally find interface-specific enum has its uses.

Interestingly, despite this change being listed as being part of the default interface implementation, most of which requires new runtime i.e. .NET Core 3.0/.NET Standard 2.1 and later, interface with nested type but without any implementation does compile and can be used in .NET Framework 4.8, as long as Roslyn CSC supporting compilation in C# 8.0 is used.

I assume this is due to the fact that CLR has been supporting nested type in interface for all this time, as Eric Lippert stated in the answer here.


There are only a few reasons why it makes sense to nest types. The main reason is to define them as private so that only the container class has access to them. The container class would use these private types in its own implementations.

Since an interface isn't an implementation, there is no good reason to nest types inside of it. It would be useless. It would be like a farmer trying to use a kitten to help him plow his fields. Theoretically, that might be possible at least to try, but it wouldn't serve any practical purpose.

Looking at the code provided, I would suggest promotion of the Connection class to a top-level type. If you want to organize your types according to function, that is what namespaces are for. Create a folder structure in your project of how the types are organized, and change the namespaces to reflect that.

Tags:

C#