null reference exception with linq .where clause

2019-02-09 20:13发布

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?

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.

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

5条回答
何必那么认真
2楼-- · 2019-02-09 20:47

Try the code below (I've assumed that contactText is 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
        });
}
查看更多
我欲成王,谁敢阻挡
3楼-- · 2019-02-09 20:50

Try:

var contact = c.address.contactItems.Where( ci => ci.contactType == ContactType.PHONE).FirstOrDefault();
 phone = contact != null ? contact.contactText : "";
查看更多
狗以群分
4楼-- · 2019-02-09 20:56

the null value is contactType so we add (ci.contactType != null)

    var phone = c.address.contactItems.Where( ci => (ci.contactType != null) && ci.contactType == ContactType.PHONE).First().contactText
查看更多
ゆ 、 Hurt°
5楼-- · 2019-02-09 21:01

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

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

If First throws an exception because there's no one with ContactType.PHONE you can use DefaultIfEmpty with a custom default value:

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

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

查看更多
神经病院院长
6楼-- · 2019-02-09 21:09
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 
  }

); }

查看更多
登录 后发表回答