I have taken a look at a C# struct FooStruct
in ILDASM, and have seen the following:
ILDASM here displays two differing declarations:
- one starting with
.class
value
public
(rear window & front window's title bar) - one starting with just
.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.
MUST a value type definition include the 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.
MAY a value type definition include the 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.
And what does the 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.
This great book contains simple
answer: when you provide extends
clause then value
flag is ignored, but if you doesn't provide
extends
and use value
then ilasm will declare given type as value type.
In other words value
was introduced as syntactic sugar, to quickly declare value type.
来源:https://stackoverflow.com/questions/15026065/how-to-declare-a-value-type-in-cil-class-value-or-just-class