C#和Java都具有原始(或“值”)类型:int,double,float等。
但是,此后C#和Java趋于分裂。
Java具有 所有原始类型的 包装类类型(在Java中是一个小的有限集),可将它们视为对象。
double/Double,
int/Integer,
bool/Boolean等。这些包装类型是引用类型(读:类),并且同样地,
null是分配给这样的类型化的表现形式/变量的有效值。Java的最新版本(1.5
/ 5 +)在原语中将隐式强制添加到其对应的包装器中。
// JavaBoolean b = true; // implicit conversion boolean -> Boolean (Java 5+)Boolean b = null; // okay, can assign null to a reference typeboolean n = null; // WRONG - null is not a boolean!
C#没有提供这种直接包装的1部分内容,因为C#通过结构支持 无限的一组值类型 ;相反,C#通过引入包装器类型来处理“空值类型”
。另外,C#和Java一样,具有从值类型到的隐式转换,其限制是T本身不是“不能为null的类型”。
Nullable<T>
T``Nullable<T>
// C#Nullable<bool> b = true; // implicit conversion bool -> bool?bool? b = true; // short type syntax, implicit conversionbool? b = null; // okay, can assign null as a Nullable-typebool b = null;// WRONG - null is not a bool
请注意,这
Nullable<T>也是一个值类型,因此遵循关于何时/是否值“在堆栈上”的标准结构规则。
回应评论:
绝对正确,作为值类型的Nullable确实可以使其 在某些情况下 具有更紧凑的内存占用 ,
因为它可以避免引用类型的内存开销:什么是Nullable
CLR中的值进行了修正,请考虑必须执行的所有提升 *** 作:
// C#object x = null;x = (bool?)true;(x as bool?).Value // true
文章Java技巧130:你知不知道你的数据的大小?讨论引用类型的内存消耗(在Java中)。需要注意的一件事是,JVM内部具有专用版本的Array,每个基本类型和Object都有一个专门的版本(但是,请注意,本文包含一些
误导性声明
)。注意对象(相对于基元)如何引起额外的内存开销和字节对齐问题。但是,C#可以将优化数组的情况扩展为
Nullable<T>类型,而JVM具有有限的特殊情况,因为JVM
Nullable<T>本身仅仅是结构类型(或“原始”)。
但是,对象仅需要较小的固定大小即可在可变插槽中维护对其的“引用”。
Nullable<LargeStruct>另一方面,类型可变的插槽必须具有空间
LargeStruct+Nullable(插槽本身可能在堆上)。请参见C#概念:值与引用类型。请注意,在上面的“提升”示例中,变量的类型是
object:
object在C#中是“根类型”(引用类型和值类型的父),而
不是 专用值类型。
1 C#语言为原始类型/公用类型支持一组固定的 别名 ,这些 别名
允许访问“友好的小写”类型名称。例如,
double是
System.Double和
int的别名
System.Int32。除非不同的
Double类型是在范围进口,
double并且
Double将参考在C#相同的类型。我建议使用别名,除非有理由这样做。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)