是否有任何惩罚,这样你只应在真正需要它时将它们设置为可空?
由于
答案 0 :(得分:20)
各种原因:
Nullable<T>
在.NET 2.0之前不存在,并且无法破坏现有代码 - 尤其是Nullable<T>
int
,我可能想要它可以为空......我希望它是一个int
,而我不是想要检查/处理空值byte[]
,现在考虑byte
是否可以为空 - 大量的额外开销; *加上它会阻止你做 blits 等* * 效果:Nullable<T>
会增加许多额外的惩罚;特别是对.HasValue
和.Value
/ .GetValueOrDefault()
的大量隐藏调用;这尤其在“提升的运算符”中显示 - 即x + y
变为类似于下面的内容,这会增加紧密循环等:
(x.HasValue && y.HasValue) ? (x.GetValueOrDefault() + y.GetValueOrDefault()) : null
同样,x == y
必须检查:
==
上使用GetValueOrDefault()
很多的开销......
答案 1 :(得分:6)
是的,有罚款。 Nullable<T>
结构包含值以及确定值的空值的布尔标志。
虽然布尔值只有一个字节,但结构与偶数字边界对齐。 int
使用四个字节的内存,但int?
需要八个字节。
答案 2 :(得分:1)
哪些值类型实际上可以为空?我一无所知。
编辑:如果您引用字符串类型,那么它不是值类型,而是引用类型。
答案 3 :(得分:0)
除了Marc Gravell的回答,请查看Nullable&lt; T&gt;的反映代码:
public struct Nullable<T> where T: struct
{
private bool hasValue;
internal T value;
public Nullable(T value)
{
this.value = value;
this.hasValue = true;
}
public bool HasValue
{
get
{
return this.hasValue;
}
}
public T Value
{
get
{
if (!this.HasValue)
{
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_NoValue);
}
return this.value;
}
}
public T GetValueOrDefault()
{
return this.value;
}
public T GetValueOrDefault(T defaultValue)
{
if (!this.HasValue)
{
return defaultValue;
}
return this.value;
}
public override bool Equals(object other)
{
if (!this.HasValue)
{
return (other == null);
}
if (other == null)
{
return false;
}
return this.value.Equals(other);
}
public override int GetHashCode()
{
if (!this.HasValue)
{
return 0;
}
return this.value.GetHashCode();
}
public override string ToString()
{
if (!this.HasValue)
{
return "";
}
return this.value.ToString();
}
public static implicit operator T?(T value)
{
return new T?(value);
}
public static explicit operator T(T? value)
{
return value.Value;
}
}
您会注意到布尔值HasValue
的存在以及属性如何使用它。
答案 4 :(得分:0)
考虑实施。 C#中的整数定义为
public struct Int32 : IComparable, IFormattable, IConvertible, IComparable<int>, IEquatable<int>
结构直接存储在堆栈中,而不是作为指向内存的指针的对象引用(引用本身在堆栈中,但分配在堆栈中)。
NULL引用只是意味着堆栈中的指针尚未初始化为堆中的某个位置。