I have taken a look at a C# struct FooStruct
in ILDASM, and have seen the following:
ILDASM here displays two differing declarations:
.class
value
public
(rear window & front window's title bar).class public
(front window)And I wonder which syntax (if not both) is the correct one for declaring a value type? Is the value
modifier strictly necessary, or optional, or a syntax error?
Short answer: Value type definitions only require
extends [mscorlib]System.ValueType
; thevalue
attribute appears to be optional and has no apparent effect.
I assume that the CLI specification (ECMA-335) would be the best place to look for an authorative answer.
value
attribute?Section II.10 deals with defining types. More specifically, subsection II.10.1.3 states:
The type semantic attributes specify whether an interface, class, or value type shall be defined. … If [the
interface
] attribute is not present and the definition extends (directly or indirectly)System.ValueType
, and the definition is not forSystem.Enum
, a value type shall be defined (§II.13). Otherwise, a class shall be defined (§II.11).
The value
attribute is not mentioned at all in the whole section.
Conclusion: A correct value type definition does not have to include value
. Deriving from System.ValueType
is sufficient.
value
modifier?The CLI standard also contains a grammar for ILASM (in section VI.C.3). According to that grammar, there exists a value
attribute for .class
type definitions. I additionally searched the standard for concrete value type definitions and found these examples:
.class public sequential ansi serializable sealed beforefieldinit System.Double extends System.ValueType …
.class private sealed Rational extends [mscorlib]System.ValueType …
.class
value
sealed public MyClass extends [mscorlib]System.ValueType …
Conclusion: A value
attribute may be included in a value type definition.
value
attribute MEAN?I tried to compile these three IL type definitions into an assembly:
.class public sealed … A extends [mscorlib]System.ValueType { … }
.class value public sealed … B extends [mscorlib]System.ValueType { … }
.class value public sealed … C extends [mscorlib]System.Object { … } // !!!
There was no compilation error, even though the value
attribute is used in a reference type declaration (see last line). Looking at the resulting assembly using Visual Studio 2012's Object Browser reveals two value types (struct
) A
and B
, and one reference type (class
) C
.
Speculation: The presence of the value
attribute has no effect whatsoever on the type definition. It is only there as a potential aid for humans in spotting value type definitions.