9

我们经常需要将值由某个字符分隔的字符串转换为列表。我想编写一个通用扩展方法,将字符串转换为指定类型的列表。这是我到目前为止所拥有的:

    public static List<T> ToDelimitedList<T>(this string value, string delimiter)
    {
        if (value == null)
        {
            return new List<T>();
        }

        var output = value.Split(new string[] { delimiter }, StringSplitOptions.RemoveEmptyEntries);
        return output.Select(x => (T)x).ToList();
    }

但我得到一个错误。

无法将类型“字符串”转换为类型“T”。

有没有更好的方法来做到这一点,或者我是否需要为不同类型的列表和 doConvert.ToInt32()等创建多个扩展方法?

更新

我正在尝试做这样的事情:

var someStr = "123,4,56,78,100";
List<int> intList = someStr.ToDelimitedList<int>(",");

或者

var someStr = "true;false;true;true;false";
List<bool> boolList = someStr.ToDelimitedList<bool>(";");
4

4 回答 4

17

Convert.ChangeType将适用于原始和许多框架类型(假设默认解析规则足够好):

return output.Select(x => (T) Convert.ChangeType(x, typeof(T)))
             .ToList();

如果您需要它来为您自己的自定义类型工作,您必须让它们实现IConvertible接口。

请记住,这不够复杂,无法使用自定义转换规则,也不够强大,无法正确处理故障(除了引发异常并使整个操作失败)。如果您需要对此的支持,请提供一个接受TypeConverter或转换委托的重载(如 mike z 的回答)。

于 2013-03-18T16:14:24.733 回答
9

没有将字符串转换为任意类型的内置方法T。您的方法必须接受某种委托:

public static List<T> ToDelimitedList<T>(this string value, string delimiter, Func<string, T> converter)
{
    if (value == null)
    {
        return new List<T>();
    }

    var output = value.Split(new string[] { delimiter }, StringSplitOptions.RemoveEmptyEntries);
    return output.Select(converter).ToList();
}
于 2013-03-18T16:14:59.377 回答
6

好像你可以使用String.Splitand Enumerable.Select

var list = "1,2,3".Split(",").Select(s => int.Parse(s));

但是,如果您必须进行扩展,请尝试此...

public static List<T> ParseDelimitedList<T>(this string value, string delimiter, Func<string, T> selector)
{
    if (value == null)
    {
        return new List<T>();
    }

    var output = value.Split(new string[] { delimiter }, StringSplitOptions.RemoveEmptyEntries);
    return output.Select(selector).ToList();
}

var list = "1,2,3".ParseDelimitedList(",", s => int.Parse(s));
于 2013-03-18T16:12:05.213 回答
6

这不是 LINQ 的完美任务吗?

您可以执行以下操作:

"1,2,3,4,5".Split(',').Select(s => Convert.ToInt32(s)).ToList();

您可以根据您的情况更改通用委托。 Select()

于 2013-03-18T16:13:54.230 回答