C# - 可空类型 Nullable Types
如您所知,不能为值类型分配空值。 例如, int i = null 会给你一个编译时错误。
C# 2.0 引入了可空类型,允许您将 null 分配给值类型变量。 您可以使用 Nullable<t> 声明可为空的类型,其中 T 是一种类型。
csharp
Nullable<int> i = null;可空类型可以表示其基础值类型的正确值范围,外加一个额外的Null。 例如,可以为 Nullable<int> 分配从 -2147483648 到 2147483647 的任何值,或null。
Nullable 类型是 System.Nullable<T> 结构的实例。 将其视为类似于以下结构的内容。
csharp
[Serializable]
public struct Nullable<T> where T : struct
{
public bool HasValue { get; }
public T Value { get; }
// other implementation
}int 类型的可空对象与普通 int 相同,只是外加了一个标志,表示 int 是否有值(或为 null)。 剩下的就是将“null”视为有效值的编译器魔法。
csharp
static void Main(string[] args)
{
Nullable<int> i = null;
if (i.HasValue)
Console.WriteLine(i.Value); // or Console.WriteLine(i)
else
Console.WriteLine("Null");
}
// 输出了null如果对象已被赋值,则 HasValue 返回 true; 如果它没有被赋值或被赋值为null,它将返回 false。
如果可空类型为 null 或未分配任何值,则使用 xx.value 访问该值将引发运行时异常。 例如,如果 i 为空, i.Value 将抛出异常:
csharp
Nullable<int> i = null;
Console.WriteLine(i.Value); //System.InvalidOperationException:“Nullable object must have a value.”type? 可空类型的简写语法
您可以使用"?"运算符来简写语法,例如 int?,long? 而不是使用 Nullable<T>。 DateTime?
csharp
int? i = null;
double? D = null;
DateTime? date = null;?? 运算符
使用'??' 运算符将可空类型分配给不可空类型。
csharp
int? i = null;
int j = i ?? 0; //如果为null的话就把0赋给j,不为null的话则把 i.value赋给j
Console.WriteLine(j);//0在上面的例子中,i 是一个可为空的 int,如果你将它分配给不可空的 int j,那么如果 i 为空,它将抛出一个运行时异常。 因此,为了降低异常风险,我们使用了"??" 运算符来指定如果 i 为空,则将 0 分配给 j。
赋值规则
可空类型与值类型具有相同的赋值规则。 如果在函数中将可空类型声明为局部变量,则必须在使用之前为其分配一个值。 如果它是任何类的字段,则默认情况下它将具有空值。
例如,以下 int 类型的 nullable 被声明和使用,而没有分配任何值。 编译器会给出 使用了未赋值的局部变量“abc” 错误:
csharp
static void Main(string[] args)
{
int? abc;
Console.WriteLine(abc); //会抛出异常。主要是防止程序员粗心
}下面的i没有赋值不会抛出异常
csharp
class MyClass
{
public Nullable<int> i;
}
class Program
{
static void Main(string[] args)
{
MyClass mycls = new MyClass();
if(mycls.i == null)
Console.WriteLine("Null");
}
}
//输出 NullNullable Helper 类
一个值为null的可空类型是没有办法比较的。如下示例
csharp
static void Main(string[] args)
{
int? i = null;
int j = 10;
if (i < j)
Console.WriteLine("i < j");
else if( i > 10)
Console.WriteLine("i > j");
else if( i == 10)
Console.WriteLine("i == j");
else
Console.WriteLine("无法比较");
}
//输出 无法比较我们可以用
csharp
static void Main(string[] args)
{
int? i = null;
int j = int.MinValue;
if (Nullable.Compare<int>(i, j) < 0)
Console.WriteLine("i < j");
else if (Nullable.Compare<int>(i, j) > 0)
Console.WriteLine("i > j");
else
Console.WriteLine("i = j");
}
//输出 i < j因为null 被认为比所有的其它的值都小
可空类型的特征
- 可空类型只能与值类型一起使用。(引用类型本身就可以为null)
- 如果值为 null,则 Value 属性将抛出 InvalidOperationException; 否则它将返回值。
- 如果变量包含一个值,则 HasValue 属性返回 true,如果它为 null,则返回 false。
- 您只能将 == 和 != 运算符用于可空类型。 对于其他比较,请使用 Nullable 静态类。
- 不允许嵌套的可为空类型。 Nullable<Nullable<int>> i; 会给出编译时错误。
