C# c语言中的空安全导航#
可能的重复项:C# c语言中的空安全导航#,c#,.net,linq,null,C#,.net,Linq,Null,可能的重复项: 在我的XML处理项目中,我必须浏览链接属性以获得所需的值。e、 g,obj1.obj2.obj3.obj4.obj…值。这个链中的任何对象都可能为空 我在谷歌上搜索了“c#中的NullSafe导航”,并找到了一些不错的文章。从一个例子中,我想到了实现自定义扩展。 现在我有一个关于这个扩展的性能的问题。 我有这三种解决方案。有人能告诉我哪一个是最好的选择(就性能而言) 选项1(使用): 备选案文3: //with try-catch.. With lowest cyclom
在我的XML处理项目中,我必须浏览链接属性以获得所需的值。e、 g,
obj1.obj2.obj3.obj4.obj…值
。这个链中的任何对象都可能为空
我在谷歌上搜索了“c#中的NullSafe导航”,并找到了一些不错的文章。从一个例子中,我想到了实现自定义扩展。
现在我有一个关于这个扩展的性能的问题。
我有这三种解决方案。有人能告诉我哪一个是最好的选择(就性能而言)
- 选项1(使用):
- 备选案文3:
//with try-catch.. With lowest cyclomatic complexity, but not a right approach. try { string x = obj1.obj2.obj3.obnj4.obj5.Value; } catch(NullReferenceException ne) { //ignore exception }
如果您的问题措辞不同,并提供了有关XML文档结构的更多信息,那么我们可以编写一个Linq查询来提取值,而不需要所有硬编码的空检查(以及我假设您也在使用的循环)。我会使用节点结构,这样您就可以执行以下操作:
var hasNullValue = false;
var x = string.Empty;
var node = firstNode;
while (node.Child != null)
{
// On the first hit we set the null flag
// and break out of the loop
if (node.Value == null)
{
hasNullvalue = true;
break;
}
node = node.Child;
}
if (!hasNullValue)
x = node.Value;
你确定选项2很糟糕吗? try/catch块不影响性能,只要catch块不向调用方抛出任何异常(它是异常抛出机制,是性能食客) 以下是一段引文: 寻找和设计 异常严重的代码可能导致 出色的表现赢得了比赛。记住 这与try/catch无关 积木:你只有在 实际的异常被抛出。你 可以使用尽可能多的try/catch块 你想要的。使用异常 你的损失是无偿的 演出例如,你应该 远离像使用 控制流的例外情况 取自 显然,只要在链式设计#1中的某个地方找到空值,设计#3就可以防止继续求值,同时也可以防止像设计#2那样编写繁重而笨拙的代码
我认为try/catch设计值得考虑…当它不正常时,其中一个obj对象为null,那么使用try-catch就完全可以了。顺便说一句,这只是一个可能有效也可能无效的想法,如果你做了一个扩展,它接受一个参数,然后把所有的东西都扔进去,然后在那里实现一个快速的逻辑级联逻辑呢?@Arsen:你提供的答案已经被关闭为dup,子答案也被标记为dup。@ArsenMkrt不。这不是那篇文章的重复。我已经看过了那个帖子,但它并没有讨论性能。而我的问题是关于性能。谢谢。@abatishchev,是的,这篇文章很有帮助。不幸的是,它并没有和我的谷歌搜索一起出现。:)感谢您的提及。请参阅选项1,该选项不会抛出NRE
obj1.IfNotNull(arg)
将编译为静态方法调用Option1StaticClass.IfNotNull(obj1,arg)
。这就是为什么在空集合上使用Linq方法时,会得到ArgumentNullException而不是NRE。谢谢Patrick,你是对的。我相应地更新了我的答案。这是假设obj1、obj2、obj3等都是同一类型的,但情况可能并非如此。。。
//with try-catch.. With lowest cyclomatic complexity, but not a right approach.
try
{
string x = obj1.obj2.obj3.obnj4.obj5.Value;
}
catch(NullReferenceException ne)
{
//ignore exception
}
var hasNullValue = false;
var x = string.Empty;
var node = firstNode;
while (node.Child != null)
{
// On the first hit we set the null flag
// and break out of the loop
if (node.Value == null)
{
hasNullvalue = true;
break;
}
node = node.Child;
}
if (!hasNullValue)
x = node.Value;