views:

294

answers:

5

I think the question is clear.

+16  A: 

Use Type.IsValueType:

Gets a value indicating whether the Type is a value type.

Use it either like this:

typeof(Foo).IsValueType

or at execution time like this:

fooInstance.GetType().IsValueType


Conversely there is also a Type.IsClass property (which should have been called IsReferenceType in my opinion but no matter) which may or may not be more appropriate for your uses based on what you are testing for.

Code always seems to read better without boolean negations, so use whichever helps the readability of your code.


As Stefan points out below, in order to properly identify structs you must be careful to avoid false positives when it comes to enums. An enum is a value type so the IsValueType property will return true for enums as well as structs.

So if you truly are looking for structs and not just value types in general you will need to do this:

Type fooType = fooInstance.GetType();
Boolean isStruct = fooType.IsValueType && !fooType.IsEnum;
Andrew Hare
A primitive type is also a value type.
Stefan Steinegger
@Stephan - It is true that all C# primitives happen to be value types but that does not mean that all value types are therefore C# primitives. `System.Guid` and `System.DateTime` are both value types but are not language primitives.
Andrew Hare
@Andrew: yes, Guid and DateTime are structs. See my answer.
Stefan Steinegger
@Stephan - You lost me. Are you saying that there is a difference between structs and value types?
Andrew Hare
Structs are simply one way that C# allows you to create value types in the resulting IL, enums are another way.
Andrew Hare
@Andrew: Structs are one kind of value types. Primitive types are another. So structs are value type, but value types not structs. (A bird is an animal, an animal is not a bird)
Stefan Steinegger
@Stephan - So would you consider `System.Int32` a value type, a struct, or a primitive?
Andrew Hare
@Andrew: int is a primitive type, which is a special case of a value type.
Stefan Steinegger
To expand my point, the term "primitive" is special and really only is reserve for certain types that have overridden the `IsPrimitiveImpl` method from `System.Type`. There is nothing stopping Microsoft from implementing a new primitive that happens to be a reference type. There is nothing about a primitive that necessitates that it must also be a value type.
Andrew Hare
The fact that all primitive types in mscorlib happen to be value types is either a design decision or a coincidence. Since the `IsPrimitiveImpl` method is defined in `System.Type` it can freely be implemented by a reference type as well. Only if this method were implemented on `System.ValueType` would you be able to say that all primitive types must be value types. The fact that all primitive types *that are currently defined* are value types is simply a coincidence.
Andrew Hare
@Andrew: I see, primitive types are actually defined as special case of structs, so I'm wrong. I added a note to my answer. I apologize for the troubles.
Stefan Steinegger
@Stephan - No trouble at all! A lively debate is good for everyone :)
Andrew Hare
Funny enough, in the C# reference here http://msdn.microsoft.com/en-us/library/s1ax56ch.aspx an enum is actually not defined as a struct. Quote: "The value types consist of two main categories: structs, enumerations". While "numeric types" are defined as structs. Doesn't sound logical.
Stefan Steinegger
Correct, enums and structs are the two value types that C# supports. A helpful way to remember this is that a struct is a kind of value type, not the other way around.
Andrew Hare
Stefan Steinegger
@Stefan - Excellent point! The OP does ask specifically about *structs*, not value types - I will edit my answer.
Andrew Hare
+2  A: 

Try the following

bool IsStruct(Type t) {
  return t.IsValueType;
}
JaredPar
+6  A: 
Type type = typeof(Foo);

bool isStruct = type.IsValueType && !type.IsPrimitive;
bool isClass = type.IsClass;

It could still be: a primitive type or an interface.


Edit: There is a lot of discussion about the definition of a struct. A struct and a value type are actually the same, so IsValueType is the correct answer. I usually had to know whether a type is a user defined struct, this means a type which is implemented using the keyword struct and not a primitive type. So I keep my answer for everyone who has the same problem then me.


Edit 2: According to the C# Reference, enums are not structs, while any other value type is. Therefore, the correct answer how to determine if a type is a struct is:

bool isStruct = type.IsValueType && !type.IsEnum;

IMHO, the definition of a struct is more confusing then logical. I actually doubt that this definition is of any relevance in praxis.

Stefan Steinegger
The primitive type thing has been discussed to death in the comments of my answer :) You don't have to worry about an interface because and interface type instance will return `false` for both `IsClass` and `IsValueType`. Also any type that implements the interface will return its true type regardless of what the reference to the type is typed as an interface or not.
Andrew Hare
@Stefan: Are you saying that primitive types are precluded from being structs? If so, you're incorrect. For example, section 11 of the C# spec says "the simple types provided by C#, such as `int`, `double`, and `bool`, are in fact all `struct` types".
LukeH
@Luke: Yes, this is indeed the definition of primitive types. I always had to know if a type is a *user defined struct*, excluding primitive types, which is normally simply referenced to as "struct". But you are right, strictly speaking primitive types are also structs.
Stefan Steinegger
A: 

cheapest is inspect a word and avoid typeof and instanceof

LarsOn
I didn't understand what is "inspect a word"
Jader Dias
A: 

This is my answer

Prager