Question

I read recently that the C# and CLI standards define different ways to handle value types and constructors.

According to the CLI specification value types can't have parameterless constructors, whereas in the C# specification value types have a default parameterless constructor. If, according to the CLI specification, you need to create a value without specifying any parameters, there's a special instruction to do that with.

So my questions are

  • why would the C# designers intentionally deviate from the CLI standard - what benefit was there to this, and why doesn't the CLI allow this functionality?
  • in my limited experience, any time I find myself using a 'special instruction' to allow for functionality that wasn't initially intended, it's usually a bit of a hack. How is this different?
Was it helpful?

Solution

In various places, it makes sense from a consistency point of view to think of value types as having a parameterless constructor. You can always create a value without providing any arguments, and that's true in both the CLI and C#. In C#, you can just use standard constructor syntax:

int x = new int();

rather than there being one syntax for this and a different syntax for invoking a "real" constructor.

Note that as of C# 2, there's the default value operator which I suppose could have been used instead:

int x = default(int);

That feels closer to the IL generated, really. I suppose it's just possible that if we'd had that to start with, C# wouldn't have "pretended" that all value types have parameterless constructors.

On the other hand, consider generics:

public void Foo<T>() where T : new()
{
    T t = new T();
}

Should that be allowed for value types? It is - but if C# didn't allow new int() then it wouldn't make much sense to allow it in a generic form...

One interesting point you may want to look at in more depth - although C# won't let you define a custom value type parameterless constructor, you can do so in IL, and C# will sometimes use it (and sometimes not) depending on the context. See my blog entry for more details.

OTHER TIPS

whereas in the C# specification value types have a default parameterless constructor

That you cannot change. So the effect is the same, just defined differently.

An important distinction between value types and class types is that class-type instances, unlike value-type instances, can only be brought into existence by calling a constructor, and will not be exposed to the outside world until either the constructor completes or explicitly exposes the object under construction. By contrast, value-type instances will be brought into existence by the creation of an enclosing struct or class-type instance with a value-type field, or by the creation of an array of value-type elements. While there wouldn't be any technical reason why Microsoft couldn't have allowed explicit parameterless constructors to be defined for structs, it would have been difficult to ensure that every struct will have its parameterless constructor run before it is exposed to the outside world, and it would have been confusing to have such a constructor run in some situations but not others.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top