c# - System.ValueType 理解

标签 c# .net-2.0

我试图创建一个 ValueType

我知道创建结构对我有帮助。

我还尝试从 System.ValueType 派生一个类型,它是一个抽象类。

但是我收到编译错误信息

".. cannot derive from special class System.ValueType"

当我看到 ValueType 的元数据时,它看起来是一个常规的抽象类。任何非密封类都应该是可派生的。但是 System.ValueType 不是密封类。

  1. 是什么让它与众不同?

  2. 是 C# 编译器认为它很特殊吗?

  3. 如果是这样,是否建议将其作为编译器设计的规则?我的意思是它是公共(public)语言规范的一部分吗?

最佳答案

ValueType 是一个善意的小谎言。

内置的数字类型(int、long、byte)、char、枚举和结构都是值类型。

这意味着它们对对象类型具有不同的标识和等价概念。如果我执行 x = y 并且 x 和 y 是引用类型,那么 x 和 y 现在指向完全相同的对象。但是,如果我执行 x = y 并且 x 和 y 是值类型,那么 x 和 y 现在是两个完全不同的对象,但恰好是相同的。 (这也反射(reflect)在 ==Equals 中,尽管它们可以被覆盖)。

(这是人们通过谈论堆栈和堆而分心的地方,如果他们还没有,那实际上是一个实现细节,虽然重要,但不是值和引用类型之间的区别点)。

现在,大多数情况下这一切都很好,但关于引用类型的一件事是它们都受益于从 System.Object 继承。值类型 int 不是真的,这也很好,因为它在很多方面都更好,它只是由可爱的 CPU 指令处理的四个字节的内存,这些指令非常擅长这样做。尽管如此,有时将 int 视为也从 System.Object 继承还是很有用的,因此您可以这样做。

当然,这意味着您可以使用 int 做一些只有在 System.Object 上才有意义的事情,所以当您这样做时,int 会被“装箱”,然后可以再次“取消装箱”。

这很好,但是如果我们想做一些特定于值类型的事情怎么办?更重要的是,如果 CLR 的设计者这样做了(特别是,他们想要一个与上述基于值的等价性相关的值类型的 GetHashCode,而不是对象具有的基于身份的等价性)怎么办?

为此,我们有 ValueType。系统将所有值类型视为继承自此类,而后者又继承自 Object。枚举又继承自值类型,所有枚举类型都继承自它,从而允许所有枚举的一些通用功能。

因此,如果您想处理所有值类型的父类(super class),请使用 ValueType,但如果您想实际创建一个值类型,请根据需要创建一个结构或枚举。


通用类型系统解释:

A structure is a value type that derives implicitly from System.ValueType, which in turn is derived from System.Object. A structure is very useful for representing values whose memory requirements are small, and for passing values as by-value parameters to methods that have strongly typed parameters. In the .NET Framework class library, all primitive data types (Boolean, Byte, Char, DateTime, Decimal, Double, Int16, Int32, Int64, SByte, Single, UInt16, UInt32, and UInt64) are defined as structures.

Like classes, structures define both data (the fields of the structure) and the operations that can be performed on that data (the methods of the structure). This means that you can call methods on structures, including the virtual methods defined on the System.Object and System.ValueType classes, and any methods defined on the value type itself. In other words, structures can have fields, properties, and events, as well as static and nonstatic methods. You can create instances of structures, pass them as parameters, store them as local variables, or store them in a field of another value type or reference type. Structures can also implement interfaces.

Value types also differ from classes in several respects. First, although they implicitly inherit from System.ValueType, they cannot directly inherit from any type. Similarly, all value types are sealed, which means that no other type can be derived from them. They also do not require constructors.

For each value type, the common language runtime supplies a corresponding boxed type, which is a class that has the same state and behavior as the value type. An instance of a value type is boxed when it is passed to a method that accepts a parameter of type System.Object. It is unboxed (that is, converted from an instance of a class back to an instance of a value type) when control returns from a method call that accepts a value type as a by-reference parameter. Some languages require that you use special syntax when the boxed type is required; others automatically use the boxed type when it is needed. When you define a value type, you are defining both the boxed and the unboxed type.

ValueType 的奇怪之处在于允许上述情况发生。

关于c# - System.ValueType 理解,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3503568/

相关文章:

C# 谷歌地球错误

javascript - ASP.NET/JavaScript - “Return False” 不阻止回发

C# DataGridView AutoSizeRowsMo​​de 问题

c# - 无效泛型类型参数的最佳异常(exception)

c# - 连接字符串最有效的方法?

c# - .NET 4.5 程序集可以引用 .NET 4.0 程序集吗?

ASP.NET - 检测转发器中的更改值?

.net - 如何在 OnStart 方法中停止服务?

c# - 在 .NET 2.0 中将位图转换为一个多页 TIFF 图像

c# - 如何在未使用 c# 加入 Microsoft Active Directory 中的域时对 ldap 进行身份验证