【问题标题】:Why cast null before checking if object is equal to null?为什么在检查对象是否等于 null 之前强制转换为 null?
【发布时间】:2010-05-23 04:09:53
【问题描述】:

我在查看“Domain Oriented N-Layered .NET 4.0 Sample App”项目时遇到了一些我不理解的代码。在这个项目中,他们经常使用如下语法来检查参数是否为空:

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

为什么要将 null 转换为要检查 null 的对象的类型?

【问题讨论】:

  • 我认为根本没有理由,因为nullnull - 它没有类型。它们可能符合一些你应该只检查相同类型的对象是否相等参数,但这对我来说似乎有点荒谬......
  • 我不知道,也许他们认为这是为了可读性/自我文档?
  • 这个类在域模型中的什么位置?
  • 离题:谷歌已经找到了这个页面,我觉得这很棒。只需谷歌“IQueryableContext”...
  • @ItzWarty,所​​以可能会在添加新帖子时对他们进行 ping 操作。我也使用了一个 WordPress 插件。

标签: c# casting null


【解决方案1】:

在给出的例子中没有意义。

虽然在这种情况下不适用,但有时需要强制转换为 null (或者至少在添加 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.");
}

【讨论】:

  • 谢谢,很好的回答。在我提到的项目中,他们确实对具体类型也使用了这种相同类型的 null 检查。
  • 但是我应该补充一点,任何使用类做这件事的人都应该被烟雾怪物追捕并杀死。这会给使用该类型的任何人带来大量不必要的压力和困惑。
  • 只是另一种情况:使用“?:”条件运算符(或三元运算符,我在过去知道它)时也需要显式的空转换。示例:日期时间?一些变量 = 0 > 1 ? DateTime.Now : (DateTime?)null;
【解决方案2】:

我不会做演员表。在这种情况下没有理由这样做。

【讨论】:

  • 我就是这么想的。这太奇怪了,因为它是 Microsoft 赞助的提供最佳实践的开源项目,而且似乎没有任何意义。
【解决方案3】:

在给定的示例中没有理由强制转换为 null。可能是为了易读性...我不知道,我不会这样做=P

在某些情况下[不包括本主题中涵盖的情况],您必须先转换为 INullable,然后才能检查变量是否为空。否则,你必须使用 object==default(TypeOfObject)...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-09
    • 2020-04-27
    • 2011-09-14
    • 2021-03-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多