2

C# 2.0 让我可以访问可空类型。当我希望数据库中的 DateTime 变量为空时,这似乎非常方便。使用可空类型时我应该担心什么,或者我是否可以过分让我拥有的每个类型都可以为空?

4

5 回答 5

8

Mitch 的 DBNull 不为空是一个好点。还要注意这一点,这是合法的 C#,但会(幸运地)产生警告:

int x = 0;

// Much later
if (x == null)

看起来它应该是非法的,但它是有效的,因为 x 可以隐式转换为可为空的 int。永远不要忽视这个警告。

您还应该注意表面上看起来与操作员不同的东西。例如,通常你会期望:

if (x <= y || x >= y)

永远都是真的——但不是 whenxyare both null。然而,x == y这将是真的 - 不像 SQL,而且确实不像 VB!提升的运算符行为是由语言而不是运行时提供的,因此您需要了解您使用的每种语言将做什么。

最后,确保您了解装箱如何处理可空类型。可空值类型的非空值被装箱,就好像它一开始就不可为空一样,空值被装箱到简单的空引用。(即实际上没有创建框 - 运行时只返回空值)。您可以从空引用或基础类型的框拆箱为可空值类型。那有意义吗?(我在 C# in Depth 中更详细地介绍了它,希望能更清楚一点……但现在是 8.45,我还没有喝过咖啡……)

编辑:好的,也许一个例子会有所帮助:

int? i = 5;
int? j = null;

object x = i; // x = reference to boxed int (there's no such thing as a "boxed nullable int")
object y = j; // y = null (a simple null reference)

i = (int?) x; // Unboxing from boxed int to int? is fine.
j = (int?) y; // Unboxing from a null reference to int? is fine too.
于 2009-01-02T08:41:35.703 回答
4

注意DBNull哪一个是不同的null

于 2009-01-02T08:33:22.913 回答
1

您还应该小心,仅在类的逻辑要求值确实可以为空的情况下才使用可空类型。这听起来可能很愚蠢,但是如果您“过火”并使所有内容都可以为空,您可能会使代码变得比必要的复杂。

当它在适当的地方使用时,我认为它可以提高代码质量,但如果它是多余的,请不要这样做。

于 2009-01-02T09:40:25.913 回答
0

有一个问题GetType(),在使用new()和泛型时特别明显:

static void Foo<T>() where T : new()
{
    T t = new T();
    string s = t.ToString(); // fine
    bool eq = t.Equals(t); // fine
    int hc = t.GetHashCode(); // fine
    Type type = t.GetType(); // BOOM!!!
}

基本上,GetType()它不是不寻常的virtual,所以它总是被强制转换(装箱)到object. 不寻常的装箱规则意味着 this 调用GetType()null这是不可能的。GetType()因此,如果您认为自己可能有空Nullable<T>对象,请不要调用。

另外 - 请注意,一些数据绑定方法不太喜欢Nullable<T>

于 2009-01-02T09:42:47.483 回答
0

互操作性可能是一个问题——例如暴露给 COM 客户端或作为 Web 服务。

于 2009-01-02T09:48:50.187 回答