对于Type
,C#中有一个属性IsClass
,但如何确定Type
是一个结构?
虽然IsValueType
是必要条件,但显然还不够。对于int
,也是值类型。
有人建议使用以下代码:
bool IsStruct = type.IsValueType && !type.IsEnum && !type.IsPrimitive;
但我不确定这是否是一种准确的方法。公式应该说明struct和其他类型之间的区别,例如DateTime
,int
和array
s。
正如一些朋友指出的那样,我指的是用户定义的结构而非预定义类型,例如DateTime
。
答案 0 :(得分:9)
从技术上讲,int也是一个结构。 IsPrimitive只是检查类型是否是CLR处理的原始类型之一。建议IsValueType && !IsEnum && !IsPrimitive
你应该没问题。
如果您只想要自定义结构(即那些不是由BCL提供的结构),您可以幸运地排除具有以"System."
开头的FullName的类型,或者仅通过过滤来包含您感兴趣的类型程序集或命名空间,或使用自定义属性。
答案 1 :(得分:2)
至少应该
bool isStruct = type.IsValueType && !type.IsEnum &&
!type.IsPrimitive && type != typeof(decimal);
答案 2 :(得分:1)
http://msdn.microsoft.com/en-us/library/bfft1t3c.aspx说: 如果Type在{bool,byte,char,decimal,double,enum,float,int,long,sbyte,short,struct,uint,ulong,ushort}中,则IsValueType为true。
http://msdn.microsoft.com/en-us/library/system.type.isprimitive%28v=vs.110%29.aspx说: 如果Type在{Boolean,Byte,SByte,Int16,UInt16,Int32,UInt32,Int64,UInt64,IntPtr,UIntPtr,Char,Double和Single}中,则IsPrimitive为真。
与IsStruct相比,您可以使用以下方法:
public static bool IsStruct(this Type type)
{
return type.IsValueType
&& !type.IsPrimitive
&& !type.IsEnum
&& type != typeof(decimal);
}
答案 3 :(得分:0)
你将会遇到困难。基础框架不知道框架其他部分中的所有预定义类型是什么。例如,期望核心框架了解System.Drawing.Point
是不合理的。
OregonGhost可能是最好的answer:获取类型信息并检查FullName
属性以查看它是否以"System."
开头。但是,您还需要检查"Microsoft."
和"FSharp"
,以及其他可能。只需在Visual Studio中单击“添加引用”,然后查看出现的名称。
然后你可能会冒太大的风险。 Microsoft通过NuGet包分发一些程序集,这些程序集中的类型通常具有以"System."
或"Microsoft."
开头的名称。您是否考虑这些“内置”类型,即使它们未随框架一起分发?
答案 4 :(得分:0)
它对我有用 !x.PropertyType.IsSecurityTransparent&& x.PropertyType.IsClass
答案 5 :(得分:0)
不是一个完美的解决方案,但您始终可以考虑使用您要搜索的程序集中的已知类型缩小搜索范围:
System.Reflection.Assembly.GetAssembly(tyepof(OneOfMyTypes))
.GetExportedTypes()
.Where(t => t.IsValueType);
有助于消除误报(更安全?),但它的便携性较差。