【问题标题】:IEnumerable extension method with String.Join returns System.Collections.Generic.List`1[System.String]带有 String.Join 的 IEnumerable 扩展方法返回 System.Collections.Generic.List`1[System.String]
【发布时间】:2018-03-09 23:55:23
【问题描述】:

我很惊讶list.Join() 返回System.Collections.Generic.List`1[System.String]

static void Main(string[] args)
{
    var list = new List<string>();

    list.Add("1024");
    list.Add("2048");

    Console.WriteLine(list.Join());

    Console.WriteLine(string.Join(", ", list));

    Console.ReadKey();
}

使用扩展方法作为

public static class StringExtensions
{
    public static string Join(this IEnumerable list)
    {
        return string.Join(", ", list);
    }
}

我不明白它不会返回我所期望的,在我认为的上下文中,我对string.join 和扩展方法非常熟悉。


我在内部认为它会是这样的

static string Join(IEnumerable list)
{
    StringBuilder sb = new StringBuilder();

    foreach (var item in list)
    {
        sb.Append(item).Append(", ");
    }

    return sb.ToString();
}

最后,我用这个版本,支持泛型和非泛型。

public static string Join(this IEnumerable list)
{
    return Join(list.Cast<object>());
}

public static string Join<T>(this IEnumerable<T> list)
{
    return string.Join(",", list);
}

【问题讨论】:

  • 它没有绑定到this oveload,因为您的 IEnumerable 不是通用的。
  • 您在StringExtensions 内的Join 方法上使用System.Collections.IEnumerable 而不是System.Collections.Generic.IEnumerable&lt;T&gt;。更改为 public static string Join(this IEnumerable&lt;string&gt; list) 并且它们都可以工作。
  • 取一个通用的IEnumerable&lt;&gt;,当你调用string.Join时,将第二个参数改为list.Cast&lt;object&gt;()

标签: c# string ienumerable extension-methods


【解决方案1】:

原因是:扩展方法将泛型List&lt;string&gt;/IEnumerable&lt;string&gt; 转换为非泛型IEnumerable

因此,您将在此处使用单个对象调用 this params overload of string.Join

public static string Join(this IEnumerable list)
{
    return string.Join(", ", list);
}

由于对象是 List&lt;string&gt;,它不会覆盖 ToString,因此您将获得类型名称作为结果:System.Collections.Generic.List1[System.String]

您可以通过以下方式更改您的扩展方法:

public static string Join(this IEnumerable list)
{
    return string.Join(", ", list.Cast<object>());
}

【讨论】:

  • 谢谢! public static string Join(this IEnumerable&lt;object&gt; list) 怎么样?
  • 这个扩展有什么好处?你已经可以直接调用 string.join 了
  • 是的,调用这个String.Join&lt;T&gt; Method (String, IEnumerable&lt;T&gt;),直接使用string.join而不使用cast&lt;&gt;
  • 我仍然更喜欢public static string Join&lt;TSource&gt;(this IEnumerable&lt;TSource&gt; list) { return string.Join(", ", list); },即使它为您提供相同的功能。使用旧的非泛型集合类型感觉很难看。此外,string.Join 的作者不包括对旧类型的支持是有原因的:新类型更好。使用我的方法,很高兴知道如果您加入值类型的类型安全集合,例如List&lt;int&gt;,则在创建字符串时不会将所有项目装箱。你的方法做拳击。
  • @Timeless 如果你使用 IEnumerable 而不是 IEnumerable&lt;&gt; 的类型,我建议你包含扩展方法的两个重载。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-04-05
  • 1970-01-01
  • 1970-01-01
  • 2019-03-17
  • 2015-11-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多