如何编写用于将分隔字符串转换为列表的通用扩展方法?
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,5
或true,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.Split
和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));
【讨论】:
这不是通用的。它只会返回int
。
打败我! @AlexFord,它不需要是通用的,因为 Select 语句将允许您提供通用转换。
不错,但也许他只是想要一个通用的解决方案?
@luis_laurent 这是一个通用的解决方案。不要重新发明***。没有理由将Split
和Select
组合成一个操作。只需独立调用这两个方法即可。
啊,我明白你的意思了。根本不使用扩展程序。以上是关于如何编写用于将分隔字符串转换为列表的通用扩展方法?的主要内容,如果未能解决你的问题,请参考以下文章