How to write a simple method, that checks whether a concrete type is a custom struct (created with public struct { };
) or not.
Checking Type.IsValueType
is not enough, because it is also true to int
, long
, etc,
and adding a check to !IsPrimitiveType
won't exclude decimal
, DateTime
and maybe some other value types. I know that most of the built in value types are actually "structs", but I only want to check for "custom structs"
These questions are mostly the same but without the answer I need:
- #1
- #2
- #3
EDIT: from the answers mentioned the "check for the 'System' prefix" was the most stable (although it's still a hack). I finally decided to create an Attribute that you have to decorate the struct with, in order the framework to pick it up as a custom struct. (The other choice I thought was to create an empty interface, and let the struct implement that empty interface, but the attribute way seemed more elegant)
Here is my original custom struct checker if someone if interested:
type.IsValueType && !开发者_JAVA技巧type.IsPrimitive && !type.Namespace.StartsWith("System") && !type.IsEnum
There is no difference between a struct defined in the framework, and a struct defined by yourself.
A couple of ideas could be:
- Keep a whitelist of framework structs, and exclude those;
- Identify the assembly (DLL) the type is defined in, and keep a whitelist of framework assemblies.
- Identify the namespace the type lives in, and exclude the framework ones.
Well, DateTime, decimal, etc meet your requirements. As far as the CLR is concerned, they are custom structs. A hack, but you can just check to see if the namespace starts with "System".
putting the above comments into an extention method:
public static class ReflectionExtensions {
public static bool IsCustomValueType(this Type type) {
return type.IsValueType && !type.IsPrimitive && type.Namespace != null && !type.Namespace.StartsWith("System.");
}
}
should work
You can check if the struct type falls under anywhere within System namespace. But again that's not a reliable solution.
Do you have a value that goes with that type? Call the ToString
method and check whether the returned string starts with "{".
If you don't have a value, check whether it has a parameterless constructor. If it doesn't, it's a constructor. If it does, use the Activator
to create an instance and call the ToString
method again.
精彩评论