How to check programmatically if a type is a struct or a class?

C#.NetClassStructTypes

C# Problem Overview


How to check programmatically if a type is a struct or a class?

C# Solutions


Solution 1 - C#

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;

Solution 2 - C#

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.

Solution 3 - C#

Extension method. It returns true for anything defined as a struct in my code but not for things like int which although they are technically structs are not for my purposes.

I needed to know when a type may have child fields or properties but was defined as a struct and not a class. Because when you alter a struct it just alters a copy, and then you have to set the original back to the altered copy to make the changes "stick".

public static bool IsStruct(this Type source) 
{
  return source.IsValueType && !source.IsPrimitive && !source.IsEnum;
}

Solution 4 - C#

I think it would be something like this:

Is it a structure

public bool IsStructure(Type LocalType)
{
    bool result = false;
    if (LocalType.IsValueType)
    {
        //Is Value Type
        if (!LocalType.IsPrimitive)
        {
            /* Is not primitive. Remember that primitives are:
            Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32,
            Int64, UInt64, IntPtr, UIntPtr, Char, Double, Single.
            This way, could still be Decimal, Date or Enum. */
            if (!LocalType == typeof(decimal))
            {
                //Is not Decimal
                if (!LocalType == typeof(DateTime))
                {
                    //Is not Date
                    if (!LocalType.IsEnum)
                    {
                        //Is not Enum. Consequently it is a structure.
                        result = true;
                    }
                }
            }
        }
    }
    return result;
}

Is it a Class

public bool IsClass(Type LocalType)
{
    bool result = false;
    if (LocalType.IsClass)
    {
        //Is Class or Delegate
        if (LocalType.GetType != typeof(Delegate))
            result = true;
    }
    return result;
}

Solution 5 - C#

Try the following

bool IsStruct(Type t) {
  return t.IsValueType;
}

Solution 6 - C#

The struct:

// determine if the type is a struct..
var isStruct = type.IsValueType && !type.IsEnum &&
               !type.IsEquivalentTo(typeof(decimal)) && 
               !type.IsPrimitive;

The class:

var isClass = type.IsClass;

The answer:

var isClassOrStruct = isStruct | isClass;

Solution 7 - C#

For every value type, there is a corresponding auto-generated class type which derives from System.ValueType, which in turn derives from System.Object. Note that value types themselves do not derive from anything, but are implicitly convertible to that class type, and instances of that class type may be explicitly converted to the value type.

Consider:

public static int GetSomething<T>(T enumerator) where T : IEnumerator<int>
{
T enumerator2 = enumerator;
enumerator.MoveNext();
enumerator2.MoveNext();
return enumerator2.Current;
}
Calling this routine on a variable of type List<int>.Enumerator will yield very different behavior from calling it on a variable of type IEnumerator<int> which happens to have an instance of List<int>.Enumerator stored within it. Even though a variable of type List<int>.Enumerator is a value type, an instance of List<int>.Enumerator stored in a variable of type IEnumerator<int> will behave as a class type.

Solution 8 - C#

	//I think it would be something like this:

	public sbyte IsStructure(Type LocalType)
	{
			sbyte result = false;
			if (LocalType.IsValueType)
			{
					//Is Value Type
					if (!LocalType.IsPrimitive)
					{
							/* Is not primitive. Remember that primitives are:
							Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32,
							Int64, UInt64, IntPtr, UIntPtr, Char, Double, Single.
							This way, could still be Decimal, Date or Enum. */
							if (!LocalType == typeof(decimal))
							{
									//Is not Decimal
									if (!LocalType == typeof(DateTime))
									{
											//Is not Date
											if (!LocalType.IsEnum)
											{
													//Is not Enum. Consequently it is a structure.
													result = true;
											}
									}
							}
					}
			}
			return result;
	}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJader DiasView Question on Stackoverflow
Solution 1 - C#Andrew HareView Answer on Stackoverflow
Solution 2 - C#Stefan SteineggerView Answer on Stackoverflow
Solution 3 - C#toddmoView Answer on Stackoverflow
Solution 4 - C#user13922443View Answer on Stackoverflow
Solution 5 - C#JaredParView Answer on Stackoverflow
Solution 6 - C#Petteri KautonenView Answer on Stackoverflow
Solution 7 - C#supercatView Answer on Stackoverflow
Solution 8 - C#Luis Pascual AntelmView Answer on Stackoverflow