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.
Some开发者_JAVA百科one 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 array
s.
As some friends have pointed out that here, I mean user defined struct and not predefined types, such as DateTime
.
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.
Should be at least
bool isStruct = type.IsValueType && !type.IsEnum &&
!type.IsPrimitive && type != typeof(decimal);
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);
}
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?
It worked for me !x.PropertyType.IsSecurityTransparent && x.PropertyType.IsClass
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.
精彩评论