简体   繁体   中英

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 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 (ie 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?

它对我有用!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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM