如何以编程方式检查类型是结构还是类?

Jad*_*ias 48 .net c# struct types class

如何以编程方式检查类型是结构还是类?

And*_*are 76

用途Type.IsValueType:

获取一个值,该值指示Type是否为值类型.

使用它像这样:

typeof(Foo).IsValueType
Run Code Online (Sandbox Code Playgroud)

或者在执行时这样:

fooInstance.GetType().IsValueType
Run Code Online (Sandbox Code Playgroud)

相反,还有一个Type.IsClass属性(应该IsReferenceType在我看来应该被调用,但无论如何),根据您正在测试的内容,这些属性可能更适合您的用途.

在没有布尔否定的情况下,代码总是看起来更好,所以请使用哪个有助于代码的可读性.


正如Stefan在下面指出的那样,为了正确识别结构,你必须小心避免误报enums.一个enum是值类型,这样IsValueType属性将返回trueenums还有structs.

因此,如果您真的在寻找structs而不仅仅是价值类型,那么您需要这样做:

Type fooType = fooInstance.GetType();
Boolean isStruct = fooType.IsValueType && !fooType.IsEnum;
Run Code Online (Sandbox Code Playgroud)

  • 基元类型也是值类型. (8认同)
  • 正确,枚举和结构是C#支持的两种值类型.记住这一点的一个有用方法是结构是一种值类型,而不是相反. (3认同)
  • @Stephan - 确实,所有 C# 原语都是值类型,但这并不意味着所有值类型都是 C# 原语。`System.Guid` 和 `System.DateTime` 都是值类型,但不是语言原语。 (2认同)
  • 为了扩展我的观点,术语“原始”是特殊的,实际上只是为某些类型保留,这些类型覆盖了“System.Type”中的“IsPrimitiveImpl”方法。没有什么能阻止 Microsoft 实现一个恰好是引用类型的新原语。原语不需要它也必须是值类型。 (2认同)

Ste*_*ger 30

Type type = typeof(Foo);

bool isStruct = type.IsValueType && !type.IsPrimitive;
bool isClass = type.IsClass;
Run Code Online (Sandbox Code Playgroud)

它仍然可以是:原始类型或接口.


编辑:关于结构的定义有很多讨论.结构和值类型实际上是相同的,IsValueType正确的答案也是如此.我通常必须知道类型是否是用户定义的结构,这意味着使用关键字struct而不是基本类型实现的类型.所以我为每个遇到同样问题的人保留答案.


编辑2:根据C#参考,枚举不是结构,而任何其他值类型.因此,如何确定类型是否为结构的正确答案是:

bool isStruct = type.IsValueType && !type.IsEnum;
Run Code Online (Sandbox Code Playgroud)

恕我直言,结构的定义比逻辑更令人困惑.我实际上怀疑这个定义与实践有任何关联.


tod*_*dmo 5

扩展方法。它返回true任何struct在我的代码中定义为的内容,但不会返回类似的东西int,尽管从技术上讲它们是结构,但这并不是我的目的。

我需要知道一种类型何时可能具有子字段或属性,但被定义为a struct而不是a class。因为当您更改a时,struct它只会更改一个副本,然后您必须将原件重新设置为更改后的副本,以使更改“粘贴”。

public static bool IsStruct(this Type source) 
{
  return source.IsValueType && !source.IsPrimitive && !source.IsEnum;
}
Run Code Online (Sandbox Code Playgroud)