如何编写用于将分隔字符串转换为列表的通用扩展方法?

Posted

技术标签:

【中文标题】如何编写用于将分隔字符串转换为列表的通用扩展方法?【英文标题】:How can I write a generic extension method for converting a delimited string to a list? 【发布时间】:2013-03-07 01:34:38 【问题描述】:

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

    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”。

有没有更好的方法来做到这一点,还是我需要为不同类型的列表创建多个扩展方法并执行Convert.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>(";");

【问题讨论】:

当涉及的唯一类型是字符串时,为什么要使用泛型方法? 字符串需要转换成不同的类型。字符串中的值可以是1,2,3,4,5true,false,false,true 您必须为此编写一些代码! 必须返回List吗?为什么不通过 IEnumerable 获得懒惰评估 【参考方案1】:

这不是 LINQ 的完美任务吗?

您可以执行以下操作:

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

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

【讨论】:

【参考方案2】:

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

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

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

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

【讨论】:

+1,哇从来不知道有Convert.ChangeType 这很好用,虽然我正在考虑像 Oliver 和 p.s.w.g 所建议的那样只使用直接 linq。 我接受这一点,因为它是我所问问题的答案,但正如 Ani 所说,它是善变的,可能更好地使用直接 LINQ,就像在@Oliver 的回答中一样。【参考方案3】:

没有将字符串转换为任意类型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();

【讨论】:

【参考方案4】:

好像你可以只使用String.SplitEnumerable.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));

【讨论】:

这不是通用的。它只会返回int 打败我! @AlexFord,它不需要是通用的,因为 Select 语句将允许您提供通用转换。 不错,但也许他只是想要一个通用的解决方案? @luis_laurent 这是一个通用的解决方案。不要重新发明***。没有理由将SplitSelect 组合成一个操作。只需独立调用这两个方法即可。 啊,我明白你的意思了。根本不使用扩展程序。

以上是关于如何编写用于将分隔字符串转换为列表的通用扩展方法?的主要内容,如果未能解决你的问题,请参考以下文章

如何将逗号分隔的字符串转换为列表?

逗号分隔的文本文件到通用列表

将逗号分隔的字符串转换为Python中的列表

如何将逗号分隔的字符串转换为 Python 中的列表?

如何将空格和逗号分隔的数字字符串转换为 int 列表? [复制]

如何将非通用排序列表保存到文件中,以便可以从文件中加载该排序列表?