0

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

我已经对其进行了修改以处理特定的分隔符,并且效果很好,但是有时,给定对象的某些属性将包含空值,我想知道是否可以扩展此代码以处理空值并替换它是基于属性类型的默认值,即如果是字符串,则将 null 替换为 string.empty,如果是数字,则将其替换为 0,如果是布尔值,则将其替换为 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、Surname 和 Age 组成,例如,您可以简单地调用它:

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

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

谢谢。

4

5 回答 5

1

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

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

source.Select(x => {
                  var value = func(x);
                  return value == null ? defaultValue : value.ToString();
              });
于 2013-06-05T01:12:52.687 回答
0

如果我理解正确的话,

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

或添加 where 查询,

.. .Where(s=>s!=null).Select(s=>func(s).ToString()) ...
于 2013-06-05T01:07:03.930 回答
0

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

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

于 2013-06-05T02:24:45.143 回答
-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 或其他东西创建另一个扩展方法),然后将其作为源传递给您的 ToSeparator 方法......会更安全。

于 2013-06-05T00:57:26.580 回答
-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();
        }));
    }

希望这对其他人有帮助!

于 2013-06-05T03:06:40.590 回答