When a storage location (variable, field, array slot, etc.) of a class type is first created, it holds null
. When a storage location of a structure type is first created, it holds an instance of the type in which every byte has been set to zero. Unlike C++, .NET provides no means for a type to exercise any say over when storage locations of that type may be created, nor what should happen when they are.
If Foo
is a class type and code creates an array bar = new Foo[100]
, the array will be created with 100 slots that don't contain references to Foo
(they're initially null
). Code that wants to make any array slot hold a reference to a Foo
will have to somehow get its hands on one, and the only way any references to Foo
will exist is if someone asks the class to create one (by calling its constructor).
By contrast, if Moo
is a structure type, creating an array boz = new Moo[100]
, the array will be created with 100 slots, each one of which is a Moo
instance. Whereas a Foo
can hold a value (null
) which doesn't refer to an instance of Foo
, none of the array slots will be capable of holding anything other than Moo
instances. Since creating an array of Moo
inherently creates instances of Moo
without the type having any say in the matter, there's really no mechanism by which a struct type could assert control over instance creation.