C# linq .where 子句的空引用异常

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14259991/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 11:12:18  来源:igfitidea点击:

null reference exception with linq .where clause

c#arrayslinqnull

提问by Arno 2501

I'm trying to get a property from an array of object that can be null (the array) and I'm always getting a null reference exception.

我试图从一个可以为空的对象数组(数组)中获取一个属性,但我总是收到一个空引用异常。

How can I tell LINQ to not process it in case it's null or to return an empty string?

如果它为空或返回空字符串,我如何告诉 LINQ 不处理它?

foreach (Candidate c in candidates) {
   results.Add(new Person 
      { 
         firstName = c.firstname, //ok
         lastName = c.Name, //ok

         // contactItems is an array of ContactItem
         // so it can be null that's why I get null exception 
         // when it's actually null
         phone = c.address.contactItems.Where( ci => ci.contactType == ContactType.PHONE).First().contactText 
      }
   );
}

I've also tried that to not take null. I don't get the mechanism to tell LINQ not to process if the array is null.

我也试过不取空。如果数组为空,我没有告诉 LINQ 不处理的机制。

phone = c.address.contactItems.Where( ci => ci != null && ci.contactType == ContactType.PHONE).First().contactText

采纳答案by Tim Schmelter

You can check if it's nullwith ?:(conditional) operator:

您可以检查它是否null?:(条件)运算符

phone = c.address.contactItems == null ? ""
    : c.address.contactItems.Where( ci => ci.contactType == ContactType.PHONE).First().contactText 

If Firstthrows an exception because there's no one with ContactType.PHONEyou can use DefaultIfEmptywith a custom default value:

如果First因为没有人ContactType.PHONE可以使用DefaultIfEmpty自定义默认值而引发异常:

c.address.contactItems.Where( ci => ci.contactType == ContactType.PHONE)
                      .DefaultIfEmpty(new Contact{contactText = ""})
                      .First().contactText 

Note that Firstnow cannot throw an exception anymore since i've provided a default value.

请注意,First现在不能再抛出异常,因为我已经提供了一个默认值。

回答by Hamlet Hakobyan

foreach (Candidate c in candidates) {
results.Add(new Person 
  { 
     firstName = c.firstname, //ok
     lastName = c.Name, //ok

     // contactItems is an array of ContactItem
     // so it can be null that's why I get null exception 
     // when it's actually null
     phone = c.address.contactItems == null
          ? string.Empty
          :c.address.contactItems.Where( ci => ci.contactType == ContactType.PHONE).First().contactText 
  }

); }

); }

回答by Chris Ayers

Try:

尝试:

var contact = c.address.contactItems.Where( ci => ci.contactType == ContactType.PHONE).FirstOrDefault();
 phone = contact != null ? contact.contactText : "";

回答by spajce

the nullvalue is contactTypeso we add (ci.contactType != null)

nullcontactType,所以我们增加(ci.contactType != null)

    var phone = c.address.contactItems.Where( ci => (ci.contactType != null) && ci.contactType == ContactType.PHONE).First().contactText

回答by Adrian Thompson Phillips

Try the code below (I've assumed that contactTextis a string).

试试下面的代码(我假设它contactText是 a string)。

You may want to look at standardising the capitalisation of your public property names to all start with an upper-case letter.

您可能希望将公共属性名称的大小写标准化为全部以大写字母开头。

foreach (Candidate c in candidates) {
    string contactText =
        c.address.contactItems
            .Where(ci => ci.contactType == ContactType.PHONE)
            .Select(ci => ci.contactText)
            .FirstOrDefault()

    results.Add(
        new Person 
        { 
            firstName = c.firstname,
            lastName = c.Name,
            phone = contactText ?? string.Empty
        });
}