如何将这段代码转换为泛型?

时间:2010-01-15 01:00:22

标签: c# generics extension-methods

我有以下扩展方法,它接受List并将其转换为逗号分隔的字符串:

    static public string ToCsv(this List<string> lst)
    {
        const string SEPARATOR = ", ";
        string csv = string.Empty;

        foreach (var item in lst)
            csv += item + SEPARATOR;

        // remove the trailing separator
        if (csv.Length > 0)
            csv = csv.Remove(csv.Length - SEPARATOR.Length);

        return csv;
    }

我想做类似的事情但是将它应用于List(而不是String of List),但是,编译器无法解析T:

    static public string ToCsv(this List<T> lst)
    {
        const string SEPARATOR = ", ";
        string csv = string.Empty;

        foreach (var item in lst)
            csv += item.ToString() + SEPARATOR;

        // remove the trailing separator
        if (csv.Length > 0)
            csv = csv.Remove(csv.Length - SEPARATOR.Length);

        return csv;
    }

我错过了什么?

4 个答案:

答案 0 :(得分:8)

首先,方法声明应为:

public static string ToCsv<T>(this List<T> list) { // }

请注意,该方法必须参数化;这是方法名称后面的<T>

其次,不要重新发明轮子。只需使用String.Join

public static string ToCsv<T>(this IEnumerable<T> source, string separator) {
    return String.Join(separator, source.Select(x => x.ToString()).ToArray());
}

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

请注意,我已经疯狂地通过接受IEnumerable<T>而不是List<T>来进一步推广该方法。

在.NET 4.0中,您可以说:

public static string ToCsv<T>(this IEnumerable<T> source, string separator) {
    return String.Join(separator, source.Select(x => x.ToString());
}

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

也就是说,我们不需要将source.Select(x => x.ToString())的结果转换为数组。

最后,有关此主题的有趣博客文章,请参阅Eric Lippert的帖子Comma Quibbling

答案 1 :(得分:7)

尝试将声明更改为

static public string ToCsv<T>(this List<T> lst){ ...

答案 2 :(得分:3)

您的函数需要一个通用参数:

static public string ToCsv<T>(this List<T> lst)
                          ^^^

答案 3 :(得分:2)

你可以使它更通用,并使用IEnumerable而不是List&lt; T>,毕竟你没有使用任何特定于列表的方法

public static string ToCsv<T>(this IEnumerable lst);