【问题标题】:Can I safely perform assignment to a possibly null property without explicit checks for null?我可以在不明确检查 null 的情况下安全地对可能为 null 的属性执行分配吗?
【发布时间】:2020-07-22 16:58:28
【问题描述】:

给定的代码如下:

a.b.c = 12;

有没有办法使用像?.?? 这样的运算符来安全地处理abnull 的情况,并且在这种情况下什么也不做。 a?.b?.c = 12 给出一个编译器错误,大概是因为 L 值可能为 null 并且您不能分配给 null。

我使用的是 C# 7.3,所以 ??= 运算符不可用,但即使是,我也不认为这是解决方案。是否可以或必须进行明确的检查?

【问题讨论】:

  • 所以你希望 12 存储在 a、b 或 c 中,以第一个非 null 为准?
  • 不,我希望它按照我的原始表达式存储,但如果 ab 为空,则不执行任何操作
  • 嗯,好的,现在和你在一起。问题是 ?. 返回一个值,而您希望有一个引用。
  • 我通常会在A 类中编写SetB()SetC() 方法。这样你就不会到处都有丑陋的if 条件。
  • 如果你可以显式调用 setter 属性方法c(12) 问题会得到解决,但我认为这也不可能!

标签: c#


【解决方案1】:

正如@user2864740 在他的回答中所写 - c# 语言不支持这样的事情。
你可以用 c# 编写它的最简洁的方式可能是这样的:

if (A?.B is null) A.B.C = 12;

但是我发现需要这样一个空安全的属性分配相当奇怪-我的意思是,如果您需要填充某个实例的属性,那么您肯定需要该实例实际存在-如果BA 在此时为空,您的程序可能不应该简单地忽略它并将 A.B.C = 12; 视为 NO-OP - 而是抛出 NullReferenceException

话虽如此,您不希望在生产代码中看到NullReferenceException,而是希望以这样一种方式编写您的代码,它是空安全的。

恕我直言,处理这种情况的方法不是避免对属性赋值 - 而是在尝试填充属性之前确保持有该属性的引用实际上不为空。

【讨论】:

  • 这是一个不错的选择。我在很大程度上同意这有点极端,但另一方面,?. 运算符的存在正是出于这种原因 - 如果没有其他原因,您的解决方案将允许单个测试而不是多个嵌套检查。
  • 是的,我同意可能存在一些需要这种结构的边缘情况。
【解决方案2】:

有没有办法使用像?这样的运算符。和 ??安全地处理 a 或 b [在分配的 LHS 上] 为空的情况..

不,没有语法可以为分配获得相同的速记绕过效果。此类尚未添加到语言中。

在当前的形式中,只计算一个值,它更类似于类似于以下的编译器错误:

(a.b.c) = 12; // LHS is a ‘value’

但是,a?.b?.. 只是在内部扩展为等价的条件链,并且 如果 已定义/实现,这也可能适用于这种假设情况。无论如何,仍然可以在提出的问题中手动完成。

【讨论】:

    猜你喜欢
    • 2021-06-21
    • 2012-10-06
    • 2021-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多