Ying
Ying

Reputation: 171

How to decide a Type is a custom struct?

For a Type, there is a property IsClass in C#, but how to decide a Type is a struct?

Although IsValueType is a necessary condition, it is obviously not enough. For an int is a value type also.

Someone suggests the following code:

bool IsStruct = type.IsValueType && !type.IsEnum && !type.IsPrimitive;

But I am not sure whether it is an accurate method. The formula should tell the difference between struct and other types such as DateTime, int and arrays.

As some friends have pointed out that here, I mean user defined struct and not predefined types, such as DateTime.

Upvotes: 17

Views: 5614

Answers (6)

jocull
jocull

Reputation: 21095

Not a perfect solution, but you can always consider narrowing the search by known types within the assemblies you wish to search:

System.Reflection.Assembly.GetAssembly(tyepof(OneOfMyTypes))
    .GetExportedTypes()
    .Where(t => t.IsValueType);

The helps eliminate false positives (safer?), but it's less portable.

Upvotes: 0

Ravindra Barapatre
Ravindra Barapatre

Reputation: 31

It worked for me !x.PropertyType.IsSecurityTransparent && x.PropertyType.IsClass

Upvotes: 0

Cyrus
Cyrus

Reputation: 2429

http://msdn.microsoft.com/en-us/library/bfft1t3c.aspx says: IsValueType is true if Type is in {bool, byte, char, decimal, double, enum, float, int, long, sbyte, short, struct, uint, ulong, ushort}.

http://msdn.microsoft.com/en-us/library/system.type.isprimitive%28v=vs.110%29.aspx says: IsPrimitive is true if Type is in {Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, Double, and Single}.

Than for IsStruct you can use method like this:

public static bool IsStruct(this Type type)
{
    return type.IsValueType 
            && !type.IsPrimitive 
            && !type.IsEnum 
            && type != typeof(decimal);
}

Upvotes: 2

Jim Mischel
Jim Mischel

Reputation: 133995

You're going to have a tough time with this. The base Framework doesn't know what all the predefined types in other parts of the Framework are. It's unreasonable to expect the core Framework to know about System.Drawing.Point, for example.

OregonGhost has probably the best answer: get the type info and check the FullName property to see if it starts with "System.". But you'll also need to check for "Microsoft." and "FSharp", and possibly others. Just click on "Add a reference" in Visual Studio, and see what names come up.

And then you might risk blocking too much. Microsoft distributes some assemblies via NuGet packages, and the types in those assemblies often have names that start with "System." or "Microsoft." Do you consider those "Built in" types even though they're not distributed with the Framework?

Upvotes: 0

Ilya Serbis
Ilya Serbis

Reputation: 22283

Should be at least

bool isStruct = type.IsValueType && !type.IsEnum &&
               !type.IsPrimitive && type != typeof(decimal);

Upvotes: 2

OregonGhost
OregonGhost

Reputation: 23759

Technically, an int is also a struct. IsPrimitive just checks if the type is one of the primitive types the CLR handles a little differently. You should be fine with the suggestion IsValueType && !IsEnum && !IsPrimitive.

If you want only custom structs (i.e. those not supplied by the BCL), you may have luck excluding types with a FullName that starts with "System.", or only including the ones you're interested in by filtering by assembly or namespace, or use a custom attribute.

Upvotes: 10

Related Questions