为什么可空< T>是一个结构? [英] Why Nullable<T> is a struct?

查看:153
本文介绍了为什么可空< T>是一个结构?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道为什么可空< T> 是值类型,如果它被设计成模仿引用类型的行为?我理解一些GC的压力,但我不觉得相信 - 如果我们希望有 INT 演技类似的参考,我们大概有具有实际参考的一切后果OK类型。我看不出有什么理由可空< T> 不仅仅是盒装 T 结构的版本

I was wondering why Nullable<T> is a value type, if it is designed to mimic the behavior of reference types? I understand things like GC pressure, but I don't feel convinced - if we want to have int acting like reference, we are probably OK with all the consequences of having real reference type. I can see no reason why Nullable<T> is not just boxed version of T struct.

作为值类型:


  1. 它仍然需要进行装箱和拆箱,多,拳击必须是比正常的结构(对待空值可为空像真正的

  2. <击>它需要一个有点不同要区别对待,当检查空(只需在做等于,没有真正的问题)

  3. <击>它是可变的,打破了结构应该是一成不变的规则(好吧,这在逻辑上是不可变的)

  4. 它需要有特殊的限制,不允许递归像可空<可空< T>>

  1. it still needs to be boxed and unboxed, and more, boxing must be a bit different than with "normal" structs (to treat null-valued nullable like real null)
  2. it needs to be treated differently when checking for null (done simply in Equals, no real problem)
  3. it is mutable, breaking the rule that structs should be immutable (ok, it is logically immutable)
  4. it needs to have special restriction to disallow recursion like Nullable<Nullable<T>>

不使可空< T> 引用类型解决问题。

Doesn't making Nullable<T> a reference type solve that issues?

改写和更新:

我修改我的理由列表了一点,但我一般的问题仍然是开放的:

I've modified my reason list a bit, but my general question is still open:

如何将引用类型可空< T> 比目前的值类型的实现更糟糕?难道只有GC压力和小,一成不变的规则?它仍然觉得很奇怪,我...

How will reference type Nullable<T> be worse than current value type implementation? Is it only GC pressure and "small, immutable" rule? It still feels strange for me...

推荐答案

究其原因,这是不会设计像一个引用类型。它被设计为像一个值类型,除了只是一个特定的。让我们来看看一些方法值类型和引用类型不同。

The reason is that it was not designed to act like a reference type. It was designed to act like a value type, except in just one particular. Let's look at some ways value types and reference types differ.

一个值类型和引用类型之间的主要区别是,值类型是独立的(包含变量实际值),而引用类型的的另一个值。

The main difference between a value and reference type, is that value type is self-contained (the variable containing the actual value), while a reference type refers to another value.

其他的一些差异是由该承担的责任。我们可以直接引用别名类型(有好的和坏的影响),这一事实来源于此。所以也做的差别是什么平等的意思是:

Some other differences are entailed by this. The fact that we can alias reference types directly (which has both good and bad effects) comes from this. So too do differences in what equality means:

一个值类型具有包含基于价值平等的概念,它可以有选择地重新定义(没有关于如何合乎逻辑的限制这种重新定义可能发生*)。引用类型具有身份的一个概念,是无意义的值类型(因为它们不能直接锯齿,所以两个这样的值可以不相同),该不能被重新定义,其也给出了其平等概念的默认。默认情况下, == 这种基于价值的平等交易,当谈到值类型†,但身份,当涉及到引用类型。此外,即使引用类型被赋予平等的基于价值的概念,并已用于 == 它从来没有失去的能力进行比较,以进行身份​​另一个参考

A value type has a concept of equality based on the value contained, which can optionally be redefined (there are logical restrictions on how this redefinition can happen*). A reference type has a concept of identity that is meaningless with value types (as they cannot be directly aliased, so two such values cannot be identical) that can not be redefined, which is also gives the default for its concept of equality. By default, == deals with this value-based equality when it comes to value types†, but with identity when it comes to reference types. Also, even when a reference type is given a value-based concept of equality, and has it used for == it never loses the ability to be compared to another reference for identity.

由这些行动包含另一个区别是,引用类型可以为空 - 指向另一个值的值可以为不参考任何值,一个值为空引用是什么。

Another difference entailed by this is that reference types can be null - a value that refers to another value allows for a value that doesn't refer to any value, which is what a null reference is.

此外,一些饲养价值类型的小的优势,涉及到这一点,因为是基于价值,他们是按值时复制传递给函数。

Also, some of the advantages of keeping value-types small relate to this, since being based on value, they are copied by value when passed to functions.

其他的一些差异,但暗示不受此承担的责任。这通常是个好主意,使一成不变的是隐含的,但不是值类型由核心差异entailed因为同时有没有考虑执行的问题被发现的优点,也有与引用类型这样做(事实上一些与安全性优势别名应用更直接引用类型),为什么人们可以打破这个方针的原因 - 所以它不是一个硬性规定(嵌套值类型所涉及的风险是如此严重减少,我将不得不作出一个嵌套的值类型可变一些疑虑即使我的风格在很大程度上偏向使得即使引用类型不变时,在所有实用)。

Some other differences are implied but not entailed by this. That it's often a good idea to make value types immutable is implied but not entailed by the core difference because while there are advantages to be found without considering implementation matters, there are also advantages in doing so with reference types (indeed some relating to safety with aliases apply more immediately to reference types) and reasons why one may break this guideline - so it's not a hard and fast rule (with nested value types the risks involved are so heavily reduced that I would have few qualms in making a nested value type mutable, even though my style leans heavily to making even reference types immutable when at all practical).

值类型和引用类型之间的一些分歧进一步,可以说是实现的细节。在一个局部变量的值类型已存储在堆栈上的价值已经被认为是一个实现细节;可能是相当明显的,如果你实现了一个堆栈,当然在某些情况下的重要一员,但不是核心的定义。它也经常夸大(为一个开始,在一个局部变量的引用类型还具有在堆栈的基准本身,另一个有很多时候一个值类型值被存储在堆)。

Some further differences between value types and reference types are arguably implementation details. That a value type in a local variable has the value stored on the stack has been argued as an implementation detail; probably a pretty obvious one if your implementation has a stack, and certainly an important one in some cases, but not core to the definition. It's also often overstated (for a start, a reference type in a local variable also has the reference itself in the stack, for another there are plenty of times when a value type value is stored in the heap).

在值类型是小一些进一步的优点涉及到这一点。

Some further advantages in value types being small relate to this.

现在,可空< T> 是一个行为像上面描述,但它可以取空值在所有的方面的值类型的类型。也许被存储在堆栈上的本地价值的事情并不那么重要(即更多的实现细节比什么都重要),但其余的是内在的它是如何定义的。

Now, Nullable<T> is a type that behaves like a value type in all the ways described above, except that it can take a null value. Maybe the matter of local values being stored on the stack isn't all that important (being more an implementation detail than anything else), but the rest is inherent to how it is defined.

可空< T> 定义为

struct Nullable<T>
{
    private bool hasValue;
    internal T value;
    /* methods and properties I won't go into here */
}



性质

大部分从这个角度实施是显而易见的。一些特殊的处理,需要允许空值分配给它 - 好像默认处理(可空< T>)已分配 - 和盒装当一些特殊处理,然后休息如下(包括可与空相等性比较)

Most of the implementation from this point is obvious. Some special handling is needed allow null to be assigned to it - treated as if default(Nullable<T>) had been assigned - and some special handling when boxed, and then the rest follows (including that it can be compared for equality with null).

如果可空< T> 是一个引用类型,那么我们就必须有特殊处理,允许发生所有的休息,为功能特殊处理沿着.NET如何帮助开发者(如我们需要进行特殊处理,使之从<$下降C $ C>值类型)。我甚至不知道这是否是可能的。

If Nullable<T> was a reference type, then we'd have to have special handling to allow for all the rest to occur, along with special handling for features in how .NET helps the developer (such as we'd need special handling to make it descend from ValueType). I'm not even sure if it would be possible.

*有我们如何让其重新定义平等的一些限制。结合与那些在缺省使用的那些规则,那么一般我们可以允许被视为两个值将被视为默认不平等平等的,但它很少有意义的考虑不平等的两个值,默认会考虑相等。一个例外是一个结构只包含值类型的情况,但如果说价值类型重新定义平等。这个优化,并且通常由设计中考虑的一个错误,而不是结果

*There are some restrictions on how we are allowed to redefine equality. Combining those rules with those used in the defaults, then generally we can allow for two values to be considered equal that would be considered unequal by default, but it rarely makes sense to consider two values unequal that the default would consider equal. A exception is the case where a struct contains only value-types, but where said value-types redefine equality. This the a result of an optimisation, and generally considered a bug rather than by design.

†一个例外是浮点类型。因为在CLI标准, double.NaN.Equals(double.NaN)值类型的定义 float.NaN.Equals(浮点.NaN)收益真正。但由于ISO 60559楠的定义,的Float.NaN ==的Float.NaN double.NaN == double.NaN 都返回假的。

†An exception is float-point types. Because of the definition of value-types in the CLI standard, double.NaN.Equals(double.NaN) and float.NaN.Equals(float.NaN) return true. But because of the definition of NaN in ISO 60559, float.NaN == float.NaN and double.NaN == double.NaN both return false.

这篇关于为什么可空&LT; T&GT;是一个结构?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆