可为空的值类型(Nullable)如何应用于数据库设计?

2026-05-25 07:041阅读0评论SEO问题
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计2082个文字,预计阅读时间需要9分钟。

可为空的值类型(Nullable)如何应用于数据库设计?

可为空的值类型(Nullable T)需注意的方面+Posted on 2011-02-15 19:10 Tecky Li阅读(5012)评论(25)编辑收藏举报+值类型不能被赋予null,但有时我们需要将简单的值类型设置为null。

可为空的值类型(Nullable<T>)需要注意的地方 Posted on 2011-02-15 19:10 Tecky Li 阅读(5012) 评论(25) 编辑 收藏 举报 值类型是不可以被赋值为null的,但有时候我们却需要简单的值类型被设置为null,比如一个查询界面上有很多的查询条件,查询条件可以使用也可以留空,这是从UI收集查询参数信息传递到后台执行查询的时候,我...

值类型是不可以被赋值为null的,但有时候我们却需要简单的值类型被设置为null,比如一个查询界面上有很多的查询条件,查询条件可以使用也可以留空,这是从UI收集查询参数信息传递到后台执行查询的时候,我们如果约定某个参数为null时,就认为用户没有使用该查询参数。

第一,它是一个结构类型,值类型

其实下面的这个变量声明就是可为空的值类型

int? number = 100;

但是number是真的值类型吗,我们使用typeof(int?)看看他的类型吧,

System.Nullable`1[System.Int32]

Nullable<T>的声明如下:

public struct Nullable<T> where T : struct

声明很清楚是Struct,这样我们就明白了,原来int?是值类型啊。

为了验证,我们使用number.GetType()来看看类型是什么,答案是System.Int32。

所以,能被赋值为null的,不一定是引用类型啊。(注:CLR本身并不支持值类型被赋值为null,最多是将每个bit都设置为0。之所以现在能够被赋值为null,是因为编译器帮我们做了转换,使得C#语法支持了这种情况。这也是回复的网友说的语法糖(Syntactic sugar)

下面的代码在控制台中打印的结果是100,而不是101:

可为空的值类型(Nullable)如何应用于数据库设计?

public void Test() { int? number = 100; ChangeValue(number); Console.WriteLine(number); } void ChangeValue(int? number) { number += 1; }

另外,大家看看下面这个代码行:

int? number = new Nullable<int>();

number变量的值居然是null。

有的朋友会说Nullable<T>是结构类型,所以装箱和拆箱是符合值类型特点的,我认为这句话是错误的。

比如:

object o = null; int? a = (int?)o; int b = (int)o;

a是可以被拆箱为null值的,而b这行代码运行时是要抛出NullReferenceException异常的。

第二,Nullable<T>可以转换为接口类型

本身Nullabe没有实现任何接口,但是请看下面的代码段:

Int32? n = 5; Int32 result = ((IComparable) n).CompareTo(5); // Compiles & runs OK Console.WriteLine(result); // 0

这是CLR为开发人员提供的福利啊,呵呵。

如果没有这个福利的话,我们就写出下面的代码才能实现同样的过程:

Int32 result = ((IComparable) (Int32) n).CompareTo(5);

第三,??操作符

顺便提提这个??(null-coalescing operator)操作符,当操作符左边的表达式为空时,返回操作符右边的值;如果操作符左边表达式值不为空时,返回操作符左边表达式值。

??操作符给我们的编码带来了很多的便利,是我们的代码更为简练,可读性更强,看下面几个示例:

private static void NullCoalescingOperator() { Int32? b = null; // The line below is equivalent to: // x = (b.HasValue) ? b.Value : 123 Int32 x = b ?? 123; Console.WriteLine(x); // "123" // The line below is equivalent to: // String temp = GetFilename(); // filename = (temp != null) ? temp : "Untitled"; String filename = GetFilename() ?? "Untitled"; }

还可以连写:

String s = SomeMethod1() ?? SomeMethod2() ?? "Untitled";

还可以用在Lamda表达式里面,增强可读性:

Func<String> f = () => SomeMethod() ?? "Untitled";

上面这些东西,希望对大家有用。

本文共计2082个文字,预计阅读时间需要9分钟。

可为空的值类型(Nullable)如何应用于数据库设计?

可为空的值类型(Nullable T)需注意的方面+Posted on 2011-02-15 19:10 Tecky Li阅读(5012)评论(25)编辑收藏举报+值类型不能被赋予null,但有时我们需要将简单的值类型设置为null。

可为空的值类型(Nullable<T>)需要注意的地方 Posted on 2011-02-15 19:10 Tecky Li 阅读(5012) 评论(25) 编辑 收藏 举报 值类型是不可以被赋值为null的,但有时候我们却需要简单的值类型被设置为null,比如一个查询界面上有很多的查询条件,查询条件可以使用也可以留空,这是从UI收集查询参数信息传递到后台执行查询的时候,我...

值类型是不可以被赋值为null的,但有时候我们却需要简单的值类型被设置为null,比如一个查询界面上有很多的查询条件,查询条件可以使用也可以留空,这是从UI收集查询参数信息传递到后台执行查询的时候,我们如果约定某个参数为null时,就认为用户没有使用该查询参数。

第一,它是一个结构类型,值类型

其实下面的这个变量声明就是可为空的值类型

int? number = 100;

但是number是真的值类型吗,我们使用typeof(int?)看看他的类型吧,

System.Nullable`1[System.Int32]

Nullable<T>的声明如下:

public struct Nullable<T> where T : struct

声明很清楚是Struct,这样我们就明白了,原来int?是值类型啊。

为了验证,我们使用number.GetType()来看看类型是什么,答案是System.Int32。

所以,能被赋值为null的,不一定是引用类型啊。(注:CLR本身并不支持值类型被赋值为null,最多是将每个bit都设置为0。之所以现在能够被赋值为null,是因为编译器帮我们做了转换,使得C#语法支持了这种情况。这也是回复的网友说的语法糖(Syntactic sugar)

下面的代码在控制台中打印的结果是100,而不是101:

可为空的值类型(Nullable)如何应用于数据库设计?

public void Test() { int? number = 100; ChangeValue(number); Console.WriteLine(number); } void ChangeValue(int? number) { number += 1; }

另外,大家看看下面这个代码行:

int? number = new Nullable<int>();

number变量的值居然是null。

有的朋友会说Nullable<T>是结构类型,所以装箱和拆箱是符合值类型特点的,我认为这句话是错误的。

比如:

object o = null; int? a = (int?)o; int b = (int)o;

a是可以被拆箱为null值的,而b这行代码运行时是要抛出NullReferenceException异常的。

第二,Nullable<T>可以转换为接口类型

本身Nullabe没有实现任何接口,但是请看下面的代码段:

Int32? n = 5; Int32 result = ((IComparable) n).CompareTo(5); // Compiles & runs OK Console.WriteLine(result); // 0

这是CLR为开发人员提供的福利啊,呵呵。

如果没有这个福利的话,我们就写出下面的代码才能实现同样的过程:

Int32 result = ((IComparable) (Int32) n).CompareTo(5);

第三,??操作符

顺便提提这个??(null-coalescing operator)操作符,当操作符左边的表达式为空时,返回操作符右边的值;如果操作符左边表达式值不为空时,返回操作符左边表达式值。

??操作符给我们的编码带来了很多的便利,是我们的代码更为简练,可读性更强,看下面几个示例:

private static void NullCoalescingOperator() { Int32? b = null; // The line below is equivalent to: // x = (b.HasValue) ? b.Value : 123 Int32 x = b ?? 123; Console.WriteLine(x); // "123" // The line below is equivalent to: // String temp = GetFilename(); // filename = (temp != null) ? temp : "Untitled"; String filename = GetFilename() ?? "Untitled"; }

还可以连写:

String s = SomeMethod1() ?? SomeMethod2() ?? "Untitled";

还可以用在Lamda表达式里面,增强可读性:

Func<String> f = () => SomeMethod() ?? "Untitled";

上面这些东西,希望对大家有用。