简体   繁体   English

带有 linq.where 子句的空引用异常

[英]null reference exception with linq .where clause

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.我试图从一个可以为 null 的对象数组(数组)中获取一个属性,但我总是得到一个 null 引用异常。

How can I tell LINQ to not process it in case it's null or to return an empty string?如果它为 null 或返回空字符串,我如何告诉 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

You can check if it's null with ?: (conditional) operator :您可以使用?: (条件)运算符检查它是否为null

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:如果First抛出异常,因为没有人使用ContactType.PHONE ,您可以将DefaultIfEmpty与自定义默认值一起使用:

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.请注意, First现在不能再抛出异常,因为我提供了默认值。

Try the code below (I've assumed that contactText is a string ).试试下面的代码(我假设contactText是一个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
        });
}

Try:尝试:

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

the null value is contactType so we add (ci.contactType != null) null值是contactType所以我们添加(ci.contactType != null)

    var phone = c.address.contactItems.Where( ci => (ci.contactType != null) && ci.contactType == ContactType.PHONE).First().contactText
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 
  }

); ); } }

avoid the argument null exception in linq like below像下面这样在 linq 中避免参数 null 异常

 Summaries = (from r in Summaries
              where r.Contains(SearchTerm)
              orderby r
              select r).ToArray();

In this case, if null passed to searchTerm you can check the null expression like below在这种情况下,如果 null 传递给 searchTerm 您可以检查 null 表达式,如下所示

 Summaries = (from r in Summaries
              where string.IsNullOrEmpty(SearchTerm) ||r.Contains(SearchTerm)
              orderby r
              select r).ToArray();

It work's for me!这个对我有用!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM