C# Featurette #1 - Reference and Value type Constraints

We've spent a lot of time talking about the major features of the C# language, but there are a number of minor features that we've added that we haven't talked about.

As we march towards our Beta release (and we make bits available), I'm going to start talking about some of these “little features” (or featurettes). Keep in mind that they are little features (not to be confused with “Little Creatures”, the 1985 Talking Heads album (what a quaint term, that. “Album”. Back in those days, when you bought a piece of music, you got honkin' big piece of vinyl, and you had to turn it over in the middle. A far cry from the ethereal download of today)).

Our first featurette - reference and value type constraints on generics types.

I've gotten asked about this capability several times. Basically, there are certain situations where you want to have a generic type where the type argument can only be a reference type or a value type.

We had discussed this early in the design process, but it wasn't something that the CLR team had time for in their schedule, so we weren't planning on it for this version. But CLR team managed to fit it in, so we decided to add it to the language. But we had to figure out the right way to express it.

We went through a few ideas. One was to have a contraint named “reference-type” and “value-type”, but that seemed to be a very verbose statement, and not really in the spirit of the C# naming. We went through a few sillier options (which have thankfully slipped my mind), and finally settled on our original choice, “class” and “struct”.

Those names aren't perfect, because of what they really mean is “reference type” or “value type”. For example, the class contraint means you can use any reference type - class, interface, or delegate. The struct constraints limits you to structs or enums. So, it's not perfect, but at least it gives the right flavor. Language design is rarely perfect.

Anyway, the syntax is exactly what you'd expect:

List<T> where T: class
{
   ...
}

[Update:

Doug asks what this enables. The list that comes to mind is some operations dealing with null, and the use of the as operator.

Thomas and Dave ask: What about “object“? Why not “ref“ and “value“?

Object wouldn't get you what you want, since everything is derived from object (yes, value types are implemented as being derived from System.ValueType, but to the language they're just derived from object).

We discussed “ref“ and “value“. We didn't like the fact that ref was a short hand (ie it wasn't “reference“), and neither of those choices had a connotation of “type-ness“ to them, while both class and struct carry a strong connotation of “type-ness“.