更具功能性的方法是否意味着更少的空引用异常?

时间:2016-12-14 15:24:42

标签: c# .net visual-studio

在审阅了Jason Roberts的pluralsite course后,我试图将一些代码库转换为更具功能性的代码。

例如,如果我们有:

    var request = new RetrieveAttributeRequest
    {
        EntityLogicalName = EntityTypeDictionary.First(kvp => kvp.Key.Name == entityTypeName).Value,
        LogicalName = attributeName
    };

    var response = (RetrieveAttributeResponse) _organizationService.Execute(request);

我可以简单地将光标放在请求上,并使用ctrl+alt+N resharper shortcut,结果将是:

        var response = (RetrieveAttributeResponse) _organizationService.Execute(new RetrieveAttributeRequest
        {
            EntityLogicalName = EntityTypeDictionary.First(kvp => kvp.Key.Name == entityTypeName).Value,
            LogicalName = attributeName
        });

另一个例子:

我们从:

开始
    var request = new RetrieveAttributeRequest
    {
        EntityLogicalName = EntityTypeDictionary.First(kvp => kvp.Key.Name == entityTypeName).Value,
        LogicalName = attributeName
    };

    var response = (RetrieveAttributeResponse) _organizationService.Execute(request);

    var attribute = response.AttributeMetadata;
    var type = attribute.AttributeType;
    var logicalName = attribute.LogicalName;

更换内联后的所有内容:

    var logicalName = ((RetrieveAttributeResponse) _organizationService.Execute(new RetrieveAttributeRequest
    {
        EntityLogicalName = EntityTypeDictionary.First(kvp => kvp.Key.Name == entityTypeName).Value,
        LogicalName = attributeName
    })).AttributeMetadata.LogicalName;

问题

用其内联等价物替换变量是否会增加代码安全性并减少空引用指针异常?

2 个答案:

答案 0 :(得分:2)

你没有检查开始的空指针。如果您的代码类似于:

var response = (RetrieveAttributeResponse) _organizationService.Execute(request);

if(response==null) throw ArgumentNullException();
var attribute = response.AttributeMetadata;

然后resharper不会提供相同的消化。我认为更流畅的方法是内联您的空值处理以符合您的期望。例如,扩展方法。

var response = _someObject.FluidComposition(...).ExceptionIfNUll().ExecuteSomething();

OR

var response = _someObject.FluidComposition(...).EmptyIfNUll().ExecuteSomething();

您可以清楚地看到上面的预期行为,但是,它只定义了操作的预期内容,而不是您将拥有的空指针异常的数量。

答案 1 :(得分:2)

没有。您提供的示例在功能上是等效的,样式更改的目的是提高可读性。

这也是对象初始化程序也添加到语言语法中的原因。例如

var myClass = new MyClass()
myClass.Value1 = someValue1;
myClass.Value2 = someValue2;

VS

var myClass = new MyClass()
{
    Value1 = someValue1,
    Value2 = someValue2
};

功能相同,但更容易快速阅读。

编写代码时,您使用的语言不仅仅是供计算机阅读和解释,还可供其他开发人员阅读。

在最后一个例子中,如果你想进行空值处理,你可以这样做:

var logicalName = ((RetrieveAttributeResponse) _organizationService.Execute(new RetrieveAttributeRequest
{
    EntityLogicalName = EntityTypeDictionary.FirstOrDefault(kvp => kvp.Key.Name == entityTypeName)?.Value,
    LogicalName = attributeName
}))?.AttributeMetadata?.LogicalName;

if (logicalName == null)
    throw new Exception("Something broke.");