【问题标题】:How to detect if element exist using a lambda expression in c#?如何使用 c# 中的 lambda 表达式检测元素是否存在?
【发布时间】:2023-03-07 21:03:01
【问题描述】:

我一直在使用 try/catch 语句来检查一个元素在解析时是否存在。显然这不是最好的方法。在我的大部分解析中,我一直在使用 LINQ(lambda 表达式),但我只是不知道如何检测元素是否存在。

我发现的一些解决方案的一个大问题是它们使用的代码比使用 try/catch 块多 3-4 倍,这有悖于目的。

我会假设代码看起来像这样:

if(document.Element("myElement").Exists())
{
   var myValue = document.Element("myElement").Value;
}

我确实找到了这个link,但在我的情况下循环是不必要的,因为我可以保证它只会出现一次,如果它存在的话。再加上必须创建一个看起来也不必要的虚拟元素的事实。似乎这不是检查的最佳方法(或好方法)。有什么想法吗?

【问题讨论】:

  • try/catch 块可能非常慢。应尽可能避免使用它们。

标签: c# xml linq lambda linq-to-xml


【解决方案1】:
XElement e = document.Element("myElement");
if (e != null)
{
    var myValue = e.Value; 
}

http://msdn.microsoft.com/en-us/library/system.xml.linq.xcontainer.element.aspx

“获取第一个(按文档顺序)具有指定 XName 的子元素。”

"如果没有指定名称的元素,则返回 Nothing。"

【讨论】:

    【解决方案2】:

    Any() 是 Linq 命令。

    Assert.IsFalse( new [] { 1, 2, 3, 4 }.Any( i => i == 5 ));
    

    【讨论】:

      【解决方案3】:

      顺便说一句,上面关于“try / catch”的评论可能是正确的,但并非在几乎所有情况下都是如此。这取决于您如何构建解决方案。在您的 Release 版本中,尽可能多地关闭闻起来像“调试”的标志,即使从远处也可以。在构建过程中,运行时被告知要记住堆栈跟踪和内容的次数越少,“try/catch”就变得越快。

      顺便说一句,#2:著名的建筑模式“告诉,不要问!” (TDA) 和“开闭原则”(OCP)禁止使用“if (!(fp = fopen(...))”等臭名昭著的代码。他们不只是鼓励你可以使用“try/catch”但强迫你这样做。因为 OCP 不仅要求在你自己的代码中服从,而且在调用外来的东西时(即像 stdio 这样的库)。

      为什么最后一句是 OCP,而不是 TDA?因为您不允许扩大现有代码的含义。坚持简单的“fopen”示例,当结果为零时你会做什么?为什么“fopen”失败了?您可以检查是否有足够的空白空间,或者文件系统是否可写。如果文件名有效。或者诸如此类。尽管如此,您的目标仍然无法实现:打开文件。想象一个无头应用程序,因此不可能有用户干预。怎么办?完全没有理由进一步摸索这些东西,因为“fopen”失败了。你需要一个后备策略。点。如果“fopen”失败了,那就失败了。

      经验法则:将您的代码视为始终成功 (KIS)。如果您的代码愿意“失败”,因为结果集通常可能包含元素或不包含元素,请将逻辑放入类中。也许您必须在不同的类 (TDA) 之间分配数据、属性、问题和方法。也许你必须根据 SLA 重新调整你的代码。

      不过,在您的情况下,请确保该元素存在。如果你不能,那不是你的错。在你的代码深处(一个包装器,前编码员的所有错误都被美化了),将所需的数据转换为另一个实体,这样就不需要“如果”了。

      【讨论】:

      • 返回 null 的代码是后续代码。检查自己范围内的值是否为 null 与违反 TDA 或 OCP 无关。
      【解决方案4】:

      Any() 是检查元素是否存在的最简单方法。

      如果您必须确保元素是唯一的,则必须执行.Count() == 1 之类的操作。或者,您可以实现自己的扩展方法,但这只是.Count == 1 的包装。

      【讨论】:

        猜你喜欢
        • 2014-05-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多