如何处理列表中的null <>使用linq

本文关键字:null linq 使用 列表 何处理 处理 | 更新日期: 2023-09-27 18:16:52

我发现这个非常方便的小段代码,使用存储在列表中的给定类的属性构建逗号分隔值列表(只需google ToComma链接-文章是在codeproject上)。

我已经修改了它来处理一个特定的分隔符,它工作得很好,但有时,一个给定对象的一些属性将包含一个null值,我想知道是否有可能扩展这段代码来处理null并将其替换为基于属性类型的默认值,即如果字符串,用字符串替换null。为空,如果是数值,用0替换,如果是bool,用false替换。

如果在问题的属性,我试图建立逗号分隔值恰好包含一个空值,它会抛出一个错误,即对象引用未设置为实例…

代码如下:

public static string ToSeparator<T, TU>(this IEnumerable<T> source, 
Func<T, TU> func, string separator)
{
    return string.Join(separator, source.Select(s => func(s).ToString()).ToArray());
}

假设你有一个列表,即列表人员,其中Person对象由FirstName,姓氏和年龄组成,然后你可以简单地调用它:

persons.ToSeparator(m => m.FirstName, "-"); 
persons.ToSeparator(m => m.Age, "-"); 

这可以用上面的代码完成吗?如果不能使用上面的代码,那么使用链接和/或lambda表达式来处理这个问题的最佳方法是什么呢?

谢谢。

如何处理列表中的null <>使用linq

您在这里要求自定义默认值。唯一有意义的是string => ""转换,因为你不能在T是值类型的类型集合中有null,除非你有List<object>之类的东西并将它们装箱。

由于default(string)实际上是null,并且对于任何引用类型都是相同的,因此您需要将默认值传递给方法。你可以使用:

source.Select(x => {
                  var value = func(x);
                  return value == null ? defaultValue : value.ToString();
              });

如果我没理解错的话,

... s=>s==null? "[Undefined]": func(s).ToString() ...

或添加where查询,

.. .Where(s=>s!=null).Select(s=>func(s).ToString()) ...

由于您正在执行传递给ToSeparator的Func,因此您无法知道该函数中可能发生什么错误。

你可以用try/catch块包围方法中函数的执行,并在捕获异常时返回其他内容。

尝试:

public static string ToSeparator<T, TU>(this IEnumerable<T> source, 
    Func<T, TU> func, string separator)
{
    return string.Join(separator, source.Select(s => (s == null ? default(TU) : func(s))
        .ToString()).ToArray());
}

请注意,如果你的选择器比父类型的属性"更深",即:

persons.ToSeparator(m => m.Address.ZipCode, "-");

这完全行不通。最好先做选择,处理null类似于我所做的(也许为SelectNullOrDefault或其他东西创建另一个扩展方法),然后将其作为源传递给你的ToSeparator方法…会更安全。

这是最终的解决方案(感谢@Ed S.,大家!)

public static string ToSeparator<T, TU>(this IEnumerable<T> source, 
Func<T, TU> func, string separator)
    {
        return string.Join(separator, source.Select(x => {
              var value = func(x);
              return value == null ? string.Empty : value.ToString();
          }));
    }

public static string ToSeparator<T, TU, TZ>(this IEnumerable<T> source, 
Func<T, TU> func, TZ defaultValue, string separator)
    {
        return string.Join(separator, source.Select(x =>
        {
            var value = func(x);
            return value == null ? defaultValue.ToString() : value.ToString();
        }));
    }

希望这对其他人有帮助!!