【发布时间】:2010-12-22 02:17:55
【问题描述】:
如何以编程方式检查类型是结构还是类?
【问题讨论】:
-
如果这是一个副本,那么不是来自给定的链接。
标签: c# .net class struct types
如何以编程方式检查类型是结构还是类?
【问题讨论】:
标签: c# .net class struct types
获取一个值,指示Type是否为值类型。
像这样使用它:
typeof(Foo).IsValueType
或在执行时像这样:
fooInstance.GetType().IsValueType
相反,还有一个Type.IsClass 属性(在我看来应该称为IsReferenceType,但不管怎样),根据您的测试内容,它可能更适合您的用途,也可能不适合。
如果没有布尔否定,代码似乎总能更好地阅读,因此请使用有助于代码可读性的任何一种。
正如 Stefan 在下面指出的那样,为了正确识别 structs,当涉及到 enums 时,您必须小心避免误报。 enum 是一种值类型,因此 IsValueType 属性将为 enums 和 structs 返回 true。
因此,如果您真的在寻找 structs 而不仅仅是一般的值类型,您将需要这样做:
Type fooType = fooInstance.GetType();
Boolean isStruct = fooType.IsValueType && !fooType.IsEnum;
【讨论】:
System.Guid 和 System.DateTime 都是值类型,但不是语言原语。
System.Type 中的IsPrimitiveImpl 方法的某些类型。没有什么能阻止 Microsoft 实现一个恰好是引用类型的新原语。原语并没有要求它也必须是值类型。
Type type = typeof(Foo);
bool isStruct = type.IsValueType && !type.IsPrimitive;
bool isClass = type.IsClass;
它仍然可以是:原始类型或接口。
编辑:关于结构的定义有很多讨论。结构体和值类型实际上是相同的,所以IsValueType 是正确答案。我通常必须知道一个类型是否是用户定义的结构,这意味着使用关键字struct 实现的类型而不是原始类型。所以我为所有和我有同样问题的人保留我的答案。
编辑 2:根据C# Reference,枚举不是结构,而任何其他值类型都是。因此,如何判断一个类型是否为结构体的正确答案是:
bool isStruct = type.IsValueType && !type.IsEnum;
恕我直言,结构的定义比逻辑更混乱。我实际上怀疑这个定义在实践中是否具有任何相关性。
【讨论】:
IsClass 返回 false和IsValueType。此外,任何实现该接口的类型都将返回其真实类型,而不管对该类型的引用是否被键入为接口。
int、double 和 bool,实际上都是 struct 类型”。
type.IsValueType && !type.IsPrimitive 不会确定该结构是否是使用关键字 struct 创建的用户定义结构。它将返回误报,例如 decimal、int? 或任何枚举。
扩展方法。对于在我的代码中定义为struct 的任何内容,它都会返回true,但不会为int 这样的东西返回,尽管它们在技术上是不符合我的目的的结构。
我需要知道一个类型何时可能有子字段或属性,但被定义为struct 而不是class。因为当您更改 struct 时,它只会更改副本,然后您必须将原件设置回更改后的副本以使更改“生效”。
public static bool IsStruct(this Type source)
{
return source.IsValueType && !source.IsPrimitive && !source.IsEnum;
}
【讨论】:
我想应该是这样的:
是结构吗
public bool IsStructure(Type LocalType)
{
bool result = false;
if (LocalType.IsValueType)
{
//Is Value Type
if (!LocalType.IsPrimitive)
{
/* Is not primitive. Remember that primitives are:
Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32,
Int64, UInt64, IntPtr, UIntPtr, Char, Double, Single.
This way, could still be Decimal, Date or Enum. */
if (!LocalType == typeof(decimal))
{
//Is not Decimal
if (!LocalType == typeof(DateTime))
{
//Is not Date
if (!LocalType.IsEnum)
{
//Is not Enum. Consequently it is a structure.
result = true;
}
}
}
}
}
return result;
}
它是一个类
public bool IsClass(Type LocalType)
{
bool result = false;
if (LocalType.IsClass)
{
//Is Class or Delegate
if (LocalType.GetType != typeof(Delegate))
result = true;
}
return result;
}
【讨论】:
试试下面的
bool IsStruct(Type t) {
return t.IsValueType;
}
【讨论】:
type.IsValueType && !type.IsEnum
对于每个值类型,都有一个对应的自动生成的类类型,它派生自 System.ValueType,而后者又派生自 System.Object。请注意,值类型本身不派生自任何东西,但可以隐式转换到该类类型,并且该类类型的实例可以显式转换为值类型。
考虑:
public static int GetSomething在List<int>.Enumerator 类型的变量上调用此例程将产生与在IEnumerator<int> 类型的变量上调用它非常不同的行为,IEnumerator<int> 恰好存储了List<int>.Enumerator 的实例。尽管List<int>.Enumerator 类型的变量是值类型,但存储在IEnumerator<int> 类型变量中的List<int>.Enumerator 实例将表现为类类型。
【讨论】:
结构:
// determine if the type is a struct..
var isStruct = type.IsValueType && !type.IsEnum &&
!type.IsEquivalentTo(typeof(decimal)) &&
!type.IsPrimitive;
班级:
var isClass = type.IsClass;
答案:
var isClassOrStruct = isStruct | isClass;
【讨论】:
//I think it would be something like this:
public sbyte IsStructure(Type LocalType)
{
sbyte result = false;
if (LocalType.IsValueType)
{
//Is Value Type
if (!LocalType.IsPrimitive)
{
/* Is not primitive. Remember that primitives are:
Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32,
Int64, UInt64, IntPtr, UIntPtr, Char, Double, Single.
This way, could still be Decimal, Date or Enum. */
if (!LocalType == typeof(decimal))
{
//Is not Decimal
if (!LocalType == typeof(DateTime))
{
//Is not Date
if (!LocalType.IsEnum)
{
//Is not Enum. Consequently it is a structure.
result = true;
}
}
}
}
}
return result;
}
【讨论】: