Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.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# 为什么可空显式强制转换LINQ运算符对空值抛出无效格式异常?_C#_Linq_Linq To Sql - Fatal编程技术网

C# 为什么可空显式强制转换LINQ运算符对空值抛出无效格式异常?

C# 为什么可空显式强制转换LINQ运算符对空值抛出无效格式异常?,c#,linq,linq-to-sql,C#,Linq,Linq To Sql,首先,我知道这个问题可以用一个简单的回答来回答,即空字符串不是空值。此外,我只是在今年早些时候通过另一个stackoverflow问题才发现了cast操作员,我对他们没有太多经验。尽管如此,它并非完全如此简单的原因是,当这些强制转换运算符与null合并运算符结合使用时,它们被称为处理错误条件(如LINQ表达式中缺少元素或属性)的优雅解决方案。我开始使用and by ScottGu作为一种方法,以简洁、半优雅的方式防止无效/丢失数据。据我所知,这似乎是将所有cast重载放在LINQ类中的首要动机之

首先,我知道这个问题可以用一个简单的回答来回答,即空字符串不是空值。此外,我只是在今年早些时候通过另一个stackoverflow问题才发现了cast操作员,我对他们没有太多经验。尽管如此,它并非完全如此简单的原因是,当这些强制转换运算符与null合并运算符结合使用时,它们被称为处理错误条件(如LINQ表达式中缺少元素或属性)的优雅解决方案。我开始使用and by ScottGu作为一种方法,以简洁、半优雅的方式防止无效/丢失数据。据我所知,这似乎是将所有cast重载放在LINQ类中的首要动机之一

因此,在我看来,处理缺失值的用例与处理空值的用例并没有什么不同,在链接的文章中,这种方法被称为处理此类情况的好方法

情景:

int length = (int?)elem.Attribute("Length") ?? 0;
如果缺少@Length属性,则强制转换将导致空值和??运算符返回0

如果@Length属性存在但为空,则强制转换将在int.tryparse上进行内部分支,并引发格式异常。当然,对于我的使用,我希望它不会返回null,这样我就可以在已经有些复杂的LINQ代码中继续使用这种方法

归根结底,这并不是说我不能想出一个解决方案,而是更重要的是,我有兴趣听到是否有一个明显的方法我错过了,或者是否有人有一个很好的角度来解释为什么缺失的价值场景得到了解决,但空值场景没有得到解决

编辑

似乎有几点我应该努力强调:

  • 链接的文章来自微软的员工,我敬佩他们,并希望他们提供指导。这些文章似乎提出(或至少提请注意)处理可选值的改进/替代方法

  • 在我的例子中,可选值有时以缺少元素或属性的形式出现,但也以空元素或值的形式出现

  • 所描述的方法在缺少值时按预期工作,但在空值时失败

  • 遵循所述方法的代码似乎是为了防止缺少可选值,但实际上是脆弱的,在特定情况下会中断。我关心的是你在实际上仍处于危险中时的保护外观

  • 如果目标元素存在但为空,则这两个链接的示例都会失败,并出现运行时异常

  • 最后,关键的一点似乎是,当您有一个契约(可能通过模式)时,所描述的方法非常有效,它确保元素或属性永远不会为空,但在契约不存在的情况下,这种方法无效,需要一个替代方法


    • 我恰好同意这种行为;如果我没有一个“id”属性/元素,那么我很乐意将其计算为null,但是如果它存在但不解析,那就不同了——空字符串只适用于极少数类型。您必须手动执行此操作,或者您可以在
      XAttribute
      等上添加扩展方法:

      public static int? ParseInt32(this XAttribute attrib) {
          if(attrib != null && string.IsNullOrEmpty(attrib.Value)) return null;
          return (int?)attrib;
      }
      

      注意:我在内部使用cast,因为它对于
      int
      来说很简单,
      .Parse
      对于
      DateTime
      等来说是一个不好的例子,它使用了一种不同的xml格式,cast在内部处理该格式。

      至于找到一种解决方法,我已经构建了下面的扩展方法。我没有想到Marc所描述的方法,它用一个可为null的int修复了这个问题,并且仍然使用??用于指定默认值的运算符。非常有创意,允许X??要继续使用的Y模式

      我想最后我可能更喜欢Marc的方法,因为它在我的赋值语句中保持了一致的模式,并且没有引入TryParseInt调用的语法混乱,因为它看起来太像是在解析-1或提供的任何默认/回退值

          elem.Attribute("ID").TryParseInt(-1)
      
          /// <summary>
          /// Parses an attribute to extract an In32 value and falls back to the defaultValue should parsing fail
          /// </summary>
          /// <param name="defaultValue">The value to use should Int32.TryParse fail</param>
          /// <returns>The parsed or default integer value</returns>
          public static int TryParseInt(this XAttribute attr, int defaultValue)
          {
              int result;
              if (!Int32.TryParse((string)attr, out result))
              {
                  // When parsing fails, use the fallback value
                  result = defaultValue;
              }
      
              return result;
          }
      
      elem.Attribute(“ID”).TryParseInt(-1)
      /// 
      ///解析属性以提取In32值,如果解析失败,则返回到defaultValue
      /// 
      ///要使用的值应为Int32.TryParse失败
      ///已解析的或默认的整数值
      公共静态int-TryParseInt(此XAttribute attr,int-defaultValue)
      {
      int结果;
      如果(!Int32.TryParse((字符串)attr,out result))
      {
      //解析失败时,请使用回退值
      结果=默认值;
      }
      返回结果;
      }
      
      您的
      .Attribute()
      方法返回哪种类型?既然内置强制转换何时会导致例如
      int.TryParse()
      ?这看起来像System.Xml中的XAttribute。Linq@Konstantin:呃。。。猎鸭:)不错。我可能会用这个作为答案,并用它来取代我提出的解决方法。我把这个问题留了一点时间,以防其他人插话,对链接文章示例的脆弱性以及如何尴尬的方面发表意见。在一种情况下,您必须通过扩展方法解决这个问题,但在另一种情况下,它是本机处理的。@John我同意对于缺少,即没有这样的属性/元素,但我不同意你是空的。事实上,当你认为额外的演员操作符(如int?)被添加(我相信)有助于使LINQ查询更容易阅读和使用…程序员将一个元素强制转换为int的目的不是为了确定该值是否可能是int吗?此外,缺少值(通过缺少元素或空元素)不是