为什么在检查对象是否等于null之前要进行null转换?

12

我正在查看“面向领域的N层.NET 4.0示例应用”项目,并发现了一些我不理解的代码。在这个项目中,他们经常使用以下语法来检查参数是否为null:

public GenericRepository(IQueryableContext context,ITraceManager traceManager)
{
    if (context == (IQueryableContext)null)
            throw new ArgumentNullException("context", Resources.Messages.exception_ContainerCannotBeNull);

为什么你要将null转换为你正在检查是否为空的对象类型?


4
我认为根本没有理由,因为null就是null,它没有类型。他们可能遵循某种“只应检查相同类型的对象是否相等”的论点,但我觉得这有点荒谬... - Travis Gockel
2
我不知道,也许他们认为这是为了可读性/自我文档化? - Alan
这个类在领域模型中的哪里? - Roman
离题:谷歌已经找到了这个页面,我觉得很神奇。只需谷歌“IQueryableContext”... - Warty
@ItzWarty,SO可能会在添加新帖子时向他们发送ping。我也使用一个WordPress插件来实现这一点。 - Josh
@R0MANARMY 这个类在命名空间 "Microsoft.Samples.NLayerApp.Infrastructure.Data.Core" 中。虽然这个项目使用许多不同的类型进行检查,但问题并不特定于某种类型。 - Jace Rhea
3个回答

14

在这个例子中,它是没有意义的。

虽然在这种情况下不适用,但有时需要强制转换空值(或至少在 default(T) 添加之前是这样)。考虑以下示例:

void DoSomething(string x) {
    ...
}

void DoSomething(object x) {
    ...
}

DoSomething(null);            // compiler can't infer the type
DoSomething((string)null);    // string type is now explicit
DoSomething(default(string)); // same as previous

编辑

我想到了另一种情况,测试相等性时需要进行转换。如果你有一个对象,它有一个重载的==运算符,允许与两个引用类型进行比较,那么与null进行比较将是模棱两可的。然而,因为IQueryableContext很可能是一个接口,并且接口不能重载==运算符,所以我仍然没有看到在你给出的例子中执行它的任何有效理由。

class CustomObject {

    private string _id;

    public CustomObject(string id) {
        _id=id;
    }

    public static bool operator ==(CustomObject lhs, CustomObject rhs) {
        if (ReferenceEquals(lhs, rhs)) { return true; }
        if (ReferenceEquals(lhs, null)) { return false; }
        if (ReferenceEquals(rhs, null)) { return false; }
        return lhs._id == rhs._id;
    }

    public static bool operator !=(CustomObject lhs, CustomObject rhs) {
        return !(lhs == rhs);
    }

    public static bool operator ==(CustomObject lhs, string rhs) {
        if (ReferenceEquals(lhs, rhs)) { return true; }
        if (ReferenceEquals(lhs, null)) { return false; }
        if (ReferenceEquals(rhs, null)) { return false; }
        return lhs._id == rhs;
    }

    public static bool operator !=(CustomObject lhs, string rhs) {
        return !(lhs==rhs);
    }

}

CustomObject o = null;
if (o == null) {
    Console.WriteLine("I don't compile.");
}

谢谢,非常好的答案。在我提到的项目中,他们也对具体类型使用了这种空值检查。 - Jace Rhea
1
但我应该补充说,任何使用类进行这种操作的人都应该被烟雾怪物追捕并杀死。这会给使用该类型的任何人带来很多不必要的压力和困惑。 - Josh
1
又是另一个案例:在使用“?”条件运算符(或三元运算符,就像我以前知道的那样)时,显式空值转换也是必需的。 例如: DateTime?someVar = 0 > 1?DateTime.Now:(DateTime?)null; - Vinicius

6

在这种情况下,我不会进行类型转换。没有必要。


这正是我所想的。这很奇怪,因为它是微软赞助的开源项目,旨在提供最佳实践,但似乎没有任何意义。 - Jace Rhea

3
在给定的例子中,没有理由将null强制转换。这可能是为了提高可读性……我不知道,我不会这样做=P
在某些情况下(不包括本主题涉及的情况),您必须在检查变量是否为空之前将其转换为INullable。否则,您必须使用object==default(TypeOfObject)……

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接