Take the 2-minute tour ×

I tried to create a ValueType.

I understand that creating a struct would help me.

I also tried to derive a type from System.ValueType which is an abstract class.

But I got a compiler error message ".. cannot derive from special class System.ValueType"

When I see the metadata of ValueType, it looks to be a regular abstract class.

  1. What made it special?

  2. Is it the C# compilor that senses it as special?

  3. If so, is it recommended as a rule for compiler design? I mean is it part of Common Language Specification?

share|improve this question
For a really good understanding of how to best create value types, checkout Effective C# (2nd Ed.), by Bill Wagner; especially item 20. It has a great deal of other very useful information too. –  Matt Ellen Aug 17 '10 at 14:50
Very nice and clear question. Saves time of reading. I encourage everyone to write question this clearly. Thanks. –  Aditya Bokade Nov 7 '14 at 9:28

7 Answers 7

up vote 19 down vote accepted

ValueType is a little white lie.

The built-in numeric types (int, long, byte), char, enums and structs are all value types.

This means that they have a different concepts of identity and equivalence to object types. If I do x = y and x and y are reference types, then x and y now point to precisely the same object. However, if I do x = y and x and y are value types, then x and y are now two completely different objects that happen to be identical. (This is also reflected in == and Equals, though that can be overridden).

(This is where people get sidetracked by talking about the stack and the heap, if they haven't already, really that's an implementation detail and while important, is not the point of the distinction between value and reference types).

Now, mostly this is all and good but one thing about reference types is that they all benefit from inheriting from System.Object. The value type int doesn't really, and that's good too as it's much better in many ways that it just be four bytes of memory handled by the lovely CPU instructions that are so good at doing so. Still, it's sometimes useful to be able to treat an int as if it also inherited from System.Object, and so you can.

Of course, this means that you may do things with int that only make sense to do on a System.Object, so when you do so the int is "boxed" and can then be "unboxed" again.

This is great, but what if we wanted to do something specific to value types? More to the point, what if the designers of the CLR did (in particular, they wanted a GetHashCode for value types that related to the value-based equivalence descibed above, rather than the identity-based equivalence that objects have)?

For this purpose we have ValueType. The system treats all value types as inheriting from this class, which in turn inherits from Object. Enum in turn inherits from value type and all enum types inherit from it, allowing some common functionality across all enums.

So, if you ever want to treat a superclass of all value types, use ValueType, but if you want to actually create a value type, create a struct or an enum as appropriate.

The Common Type System explanation:

A structure is a value type that derives implicitly from System.ValueType, which in turn is derived from System.Object. A structure is very useful for representing values whose memory requirements are small, and for passing values as by-value parameters to methods that have strongly typed parameters. In the .NET Framework class library, all primitive data types (Boolean, Byte, Char, DateTime, Decimal, Double, Int16, Int32, Int64, SByte, Single, UInt16, UInt32, and UInt64) are defined as structures.

Like classes, structures define both data (the fields of the structure) and the operations that can be performed on that data (the methods of the structure). This means that you can call methods on structures, including the virtual methods defined on the System.Object and System.ValueType classes, and any methods defined on the value type itself. In other words, structures can have fields, properties, and events, as well as static and nonstatic methods. You can create instances of structures, pass them as parameters, store them as local variables, or store them in a field of another value type or reference type. Structures can also implement interfaces.

Value types also differ from classes in several respects. First, although they implicitly inherit from System.ValueType, they cannot directly inherit from any type. Similarly, all value types are sealed, which means that no other type can be derived from them. They also do not require constructors.

For each value type, the common language runtime supplies a corresponding boxed type, which is a class that has the same state and behavior as the value type. An instance of a value type is boxed when it is passed to a method that accepts a parameter of type System.Object. It is unboxed (that is, converted from an instance of a class back to an instance of a value type) when control returns from a method call that accepts a value type as a by-reference parameter. Some languages require that you use special syntax when the boxed type is required; others automatically use the boxed type when it is needed. When you define a value type, you are defining both the boxed and the unboxed type.

The strangeness of ValueType is to allow the above to happen.

share|improve this answer
I appreciate you explanation. But in reality how did they make it as special is my question still. System.ValueType is not sealed and abstract. So it should be eligible to be a parent class. (So it did for Enum, Int32 etc.) If C# compiler treats it special, it should be in other languages as well (VB.Net, J#). But i don't see a note in Microsoft Common Language Specification. msdn.microsoft.com/en-us/library/12a7a7h3.aspx . So I still think there's something hidden, and this has a different explanation. –  SaravananArumugam Aug 17 '10 at 15:57
@Saravanandss Added the explanation from the Common Type System documenation above. Not that it insists that value types implicitly derive from System.ValueType, while also insisting that they can't derive from anything. Resolving the contraction is done by having the weirdness you describe. –  Jon Hanna Aug 17 '10 at 16:08
Looks like a duck, quacks like a duck, swims like a duck, it's a duck. But it isn't. –  Hans Passant Aug 17 '10 at 19:06

Structures are value types. Value types are special because they are allocated on the stack rather than the heap. To "inherit" from ValueType, you must create a struct.

share|improve this answer
Structure is value type is a theory. But my question was different, What makes the System.ValueType special? Its not a sealed class, but it doesn't allow derivation. –  SaravananArumugam Aug 17 '10 at 14:52
@Saravanandss, "structure is a value type" is a fact, not a theory. It really does happen. –  Jon Hanna Aug 17 '10 at 15:30

Not being able to derive from ValueType is specific to the C# compiler. If we look at managed C++ code:

value class Foo {};
value class Foo : System::ValueType {};

Both of these compile and are identical. Of course,

ref class Foo : System::ValueType {};

Will give error C3050: a ref class cannot inherit from 'System::ValueType'.
Not sure what other compilers allow.

If you want to derive from ValueType in C#, use struct and not class, and the compiler takes care of it.

share|improve this answer

C# does not allow value types to inherit from other classes. Value types (struct) can implement interfaces.

share|improve this answer

you cannot subclass ValueType directly. All value types derives from ValueType implicitly. Unlike with reference types, you cannot derive a new type from a value type. However, like reference types, structs can implement interfaces.

see MSDN to know more

share|improve this answer
Any non sealed class should be derivable. But System.ValueType is not a sealed class. And it says itself a special class. What makes it special? is my question –  SaravananArumugam Aug 17 '10 at 14:54
@Saravanandss CLR .NET dose it special. –  Arseny Aug 17 '10 at 15:03
  1. A 'class' extends 'System.Object', a 'struct' extends 'System.ValueType'. If you could make a class extend 'System.ValueType', then there wouldn't be much point to the 'struct' keyword.

  2. Yes

  3. Yes. There should only be one way to accomplish any given thing. As soon as two methods of doing something are provided, you've just make everything more complicated. General rule.

share|improve this answer
Need to bear in mind that everything in .NET is ultimately System.Object. –  Michael Aug 17 '10 at 14:48
I disagree to this. In the programming world there are many ways to do things. For instance, if (a == b) c = 0; else c = 1; is equivalent to c = (a == b) ? 0 : 1; And Nullable<Int32> s = null; Int32? s = null; are equal. There's no rule to say that there should be only one way to accomplish a thing. –  SaravananArumugam Aug 17 '10 at 15:09
There should always be as many ways as possible to do something. There should always be as few ways as possible that things are done for you. Both of these free developers. –  Jon Hanna Aug 17 '10 at 15:37
@Michael: Yes, so? I don't see the relevance. @Sara: The question is about compiler design, not about programming language design. The two are different. @Jon: Indeed, and when you design the compiler so that there's only one way to do something then you get only one way to have that thing done for you by the compiler. –  Task Aug 17 '10 at 17:34
Wasn't aimed at you, rather at a newbie, as they may not think that value types are still of type object ultimately. –  Michael Aug 17 '10 at 18:12

This is what perplexes me... Enum is derived from ValueType. Which makes me think the above is just a compiler restriction.

[Serializable, ComVisible(true)]
public abstract class Enum : ValueType, IComparable, IFormattable, IConvertible
share|improve this answer
In some contexts, the runtime will treat types differently based upon whether they derived from ValueType. If a compiler allowed one to create a class which derived from ValueType and didn't include any code, such a class would behave like a struct. If the class did include code, such code likely wouldn't work because structs and classes access this differently; if the compiler didn't know this was a struct, it would generate the wrong code to access it. –  supercat Sep 26 '12 at 23:40

Your Answer


