【发布时间】:2012-02-23 21:51:23
【问题描述】:
我正在使用某人的 SDK,但文档没有告诉我什么是结构或类。
我怎样才能知道呢? typeof 或 GetType 只需显示名称即可。
我想在 IDE(VS2010) 中找到它;通过编码的方法也是可以接受的。
【问题讨论】:
标签: c# visual-studio class types struct
我正在使用某人的 SDK,但文档没有告诉我什么是结构或类。
我怎样才能知道呢? typeof 或 GetType 只需显示名称即可。
我想在 IDE(VS2010) 中找到它;通过编码的方法也是可以接受的。
【问题讨论】:
标签: c# visual-studio class types struct
从编程上讲,你可以使用GetType().IsValueType。
在 Visual Studio 中,您还可以使用 对象浏览器(如下所示,位于视图 -> 对象浏览器下)进行检查。
【讨论】:
如前所述,您可以通过在类型对象上调用IsValueType 来确定泛型类型是类类型还是值类型。但是请注意,测试对象 instance 是否为值类型是没有意义的。尽管 C# 会假装引用类型的字段可以保存值类型的实例,但这是一种错觉。对于每个值类型,都有一个具有相同名称和字段的相应类类型。对持有对此类实例的引用的存储位置调用 GetType().IsValueType 将报告 true,即使该存储位置实际上持有对类对象的引用。这可以通过实现变异接口的结构轻松演示(例如List<string>.Enumerator,我将其简称为LSE)。
存储在LSE 类型变量中的LSE 将表现为值类型。将即将返回列表的第三项的LSE 复制到另一个类型为LSE 的变量将产生第二个独立 枚举器,它也将返回第三项。一个可以从任一枚举器读取项目而不会影响另一个。相比之下,如果一个人有一个IEnumerable<string> 类型的变量,它包含对LSE 的引用,并且一个人将其复制到另一个IEnumerable<string> 类型的变量,那么一个人将有第二个对相同的引用 i> 枚举器。从一个枚举器读取项目也将推进另一个。换句话说,将LSE 复制到引用类型的存储位置会产生类似于引用类型的东西,因为在幕后,它实际上是一个。
请注意,在存储位置调用GetType 不会显示它是否拥有真正的值类型,或者它是否拥有与值类型关联的类的对象。在前一种情况下,系统将创建一个与值类型关联的类的新实例并在其上调用GetType,因此在这两种情况下,GetType 调用实际上将在类类型实例上处理。
【讨论】:
List<string>.Enumerator 类型的值作为参数类型IEnumerable<string> 传递给例程,则结果将表现为类类型。 CLS 规范(详细说明了运行典型 C# 实现的环境)基本上用我描述的术语来描述事物。 C# 可能会假装装箱的值类型仍然是值类型,但是由于 CLS 规范说“在幕后”它们实际上不是,并且由于它们的行为类似于类类型而不是值类型,所以我不明白 C#定义很有帮助。
IEnumerable<string> 的类型的实例复制到IEnumerable<string> 类型的变量创建一个新实例,以及何时简单复制对现有实例的引用?”和“可以将Integer 作为具有class 约束的泛型类型参数传递吗?”如果将装箱的值类型识别为实际上是类对象,则上述问题的答案很简单:类类型对象表现出引用行为;值类型存储位置表现出值类型行为。
IEnumerable<string> 类型的参数,是否有任何方法可以确定它是值类型还是没有反射的类类型? CLS 规范说,这样的事物将在内部作为类类型处理(无论是独立类,还是与值类型关联的同名类),并且该事物将具有与类类型无法区分的行为。如果它在内部是一个类类型,并且它的行为类似于一个,那么将它视为其他任何东西会有什么帮助?