Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/266.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 功能性更强的方法是否意味着空引用异常更少?_C#_.net_Visual Studio - Fatal编程技术网

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

C# 功能性更强的方法是否意味着空引用异常更少?,c#,.net,visual-studio,C#,.net,Visual Studio,在回顾了JasonRoberts的一篇文章之后,我试图将我们的一些代码库转换为更具功能性的风格 例如,如果我们有: var request = new RetrieveAttributeRequest { EntityLogicalName = EntityTypeDictionary.First(kvp => kvp.Key.Name == entityTypeName).Value, LogicalName = attributeName

在回顾了JasonRoberts的一篇文章之后,我试图将我们的一些代码库转换为更具功能性的风格

例如,如果我们有:

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

    var response = (RetrieveAttributeResponse) _organizationService.Execute(request);
我可以简单地将光标放在请求上,然后使用,结果将是:

        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;
问题


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

您最初没有检查空指针。如果您的代码类似于:

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

if(response==null) throw ArgumentNullException();
var attribute = response.AttributeMetadata;
那么resharper就不会提供同样的建议了。我认为一种更流畅的方法是内联null处理,以符合您的期望。例如,扩展方法

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


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

否。您给出的示例在功能上是等效的,样式更改的目的是提高可读性

这也是在语言语法中添加对象初始值设定项的原因。比如说

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

它在功能上是等效的,但更易于快速阅读

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

在上一个示例中,如果要执行null处理,可以执行以下操作:

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.");

为什么会这样?查看上一个代码段——如果
Execute()
返回
null
,访问
AttributeMetadata
将触发NRE。这是一个非常主观的问题,没有适合堆栈溢出的好答案。就个人而言,我不太关注“更实用”而更关注“验证您的参数”和“不要返回
null
”。正确编写的代码没有NRE,因为带有
null
参数的第一次调用抛出
ArgumentNullException
(易于调试),并且从不取消引用
null
,因为该方法要么抛出且从不返回,要么记录为返回
null
,并在客户端进行检查。剩下的是真正的虫子,而对付这些虫子却没有什么灵丹妙药;对
null
的最好防御可以说是从语言中根除它。但这绝非易事。空对象模式不是最佳模式,因为它所能做的只是在出现
null
时提供一些合理的不做任何事情的实现。这种实现并不总是存在的。有时候,有些事情确实应该发生,而不让它发生就是一个错误。但是当然,如果您满足于不发生任何事情而不是异常,那么空对象(和)就是您想要的。如果您有
IMyClass
,您可以轻松地生成一个
MyClassNull
,它实现
IMyClass
,这样每个方法都不做任何事情。然后,空对象是
公共静态只读IMyClass null=new MyClassNull()
。这些实现甚至可以通过模板或反射生成。当然,显而易见的问题是,您需要为所有内容提供一个接口。有些人在单元测试中有这样的想法,但如果你没有,那就是重构的时候了。(另外,您需要为返回值的方法制定一个策略——它们将返回什么?更多空对象?异常?)
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.");