C# 是否有重要原因不为每个对象引用使用安全导航?

C# 是否有重要原因不为每个对象引用使用安全导航?,c#,.net,c#-4.0,C#,.net,C# 4.0,我一直在向我的团队介绍一些新的C语言特性——安全导航就是其中之一 是否存在任何重要的性能原因来避免对每个对象/属性调用使用安全导航 e、 g: vs 我知道这使得每个字段都是空检查的——但是在一个紧密的循环之外,它捕获的bug不值得吗?或者这会鼓励懒惰的编码吗 编辑: 我在这个话题上找到了一个答案,希望对其他人有帮助 这抓到的虫子不值得吗 恰恰相反:在任何地方应用安全导航都会隐藏bug,而不是捕获它们 错误地导航空引用是实现中的一个错误,这可能意味着两件事之一: 从中导航的字段不应为空 您忘记了

我一直在向我的团队介绍一些新的C语言特性——安全导航就是其中之一

是否存在任何重要的性能原因来避免对每个对象/属性调用使用安全导航

e、 g:

vs

我知道这使得每个字段都是空检查的——但是在一个紧密的循环之外,它捕获的bug不值得吗?或者这会鼓励懒惰的编码吗

编辑:

我在这个话题上找到了一个答案,希望对其他人有帮助

这抓到的虫子不值得吗

恰恰相反:在任何地方应用安全导航都会隐藏bug,而不是捕获它们

错误地导航空引用是实现中的一个错误,这可能意味着两件事之一:

从中导航的字段不应为空 您忘记了检查合法为空的字段 对于案例2,应用安全导航是一个不错的选择,因为它可以让您用更少的代码执行空检查。但是,对于案例1来说,这是一个糟糕的选择,因为它让对象或变量保持在从程序逻辑的角度来看是不正确的状态


这就是为什么程序员在应用安全导航时应该运用他们的判断力,分别决定每种情况。

1 Null实际上是一个无效的逻辑

public string ProcessHash(User user) 
{
    var hash = user?.Password?.Hash
    ...
}
它被称为安全导航,不容易检查空值是有原因的。假设你注定要阅读上面的代码。 ProcessHash是否期望用户参数为空参数?如果是,它的Password属性也应该为null吗?你怎么知道以前的编码员是否使用过?。而不是就因为他是猫王的粉丝?你必须分析整个代码才能找到答案

2 Null的含义与代码中的不可用性不同

盲人能看见什么?黑暗还是什么都没有

什么是空的购物篮

// This is a good
Basket<Grocery> basket = new Basket<Grocery>();
var count = basket.Count(); // returns 0

// This smells bad!
Basket<Grocery> basket = null
var count = basket?.Count ?? 0;

旁注:单词选择-通常不用于隐藏/防止含义。。。NRE最好在某些字段意外为null时捕获错误。这假设null是这些对象的有效和预期状态,这是否符合您的业务规则?@DaveShaw不幸的是,这是大多数C代码的实际情况。null是对象的默认状态。这基本上是在错误恢复下一步。安全导航主要是给不好的开发人员一个借口来写不好的代码,就像大多数javascript代码是这样写的。你应该很少使用它。很好的答案,正是我想要的一般指导方针。谢谢安全导航就像对代码应用try/catch/continue,主要导致代码非常不安全,令人困惑。我个人尽量不使用它。如果一个字段可以为null,只需检查它是否为null并返回保护子句或处理null,等等。。。很少使用操作符。
public string ProcessHash(User user) 
{
    var hash = user?.Password?.Hash
    ...
}
// This is a good
Basket<Grocery> basket = new Basket<Grocery>();
var count = basket.Count(); // returns 0

// This smells bad!
Basket<Grocery> basket = null
var count = basket?.Count ?? 0;
var resp = this.Bind<IceCreamDTO>()?.Validate()?.ToEntity()?.Insert()?.ToResponse();
// That's not how this works. that's not how any of this works.
try 
{
    var resp = this.Bind<IceCreamDTO>()?.Validate()?.ToEntity()?.Insert()?.ToResponse();
    ...
} catch (ValidationException exp) 
{
     return exp.Errors.ToResponce();
}
// Privacy violation
bool passwordValidation = user?.Password?.Hash?.Validate(hash);

// Property Security
bool passwordValidation = PasswordHash.Validate(user, hash);