如何在列表中处理null<>当使用linq时

时间:2013-06-05 00:28:23

标签: c# linq lambda

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

我已修改它以处理特定的分隔符并且它工作得很好,但有时,给定对象的某些属性将包含空值,我想知道是否可以扩展此代码来处理null并将其替换为基于属性类型的默认值,即如果是string,则用string.empty替换null,如果是numeric,则将其替换为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());
}

假设你有一个列表,即List人员,其中Person对象由FirstName,Surname和Age组成,你可以简单地调用它:

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

可以使用上面的代码完成吗?如果使用上面的代码无法完成,那么使用link和/或lambda表达式处理它的最佳方法是什么。

感谢。

5 个答案:

答案 0 :(得分:1)

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

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

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

答案 1 :(得分:0)

如果我理解正确,

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

或添加where查询,

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

答案 2 :(得分:0)

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

您可以使用try / catch块在方法中执行func,并在捕获异常时返回其他内容。

答案 3 :(得分:-1)

尝试:

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或其他东西创建另一个扩展方法),然后将THAT作为源传递到ToSeparator方法......会更安全。

答案 4 :(得分:-1)

这是最终解决方案(感谢@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();
        }));
    }

希望这有助于其他人!!