我能够将逗号分隔的字符串转换为IList<int>
但是如何修改它以获取IList<T>
,其中T将作为输入参数之一传递?
即如果我需要IList<int>
,我将通过&#34; int&#34;作为参数,如果我需要IList<string>
我将传递&#34;字符串&#34;作为参数。
我的想法是通过输入参数获取类型是int还是string并使用反射并将字符串转换为相应的列表
将逗号分隔的字符串转换为IList<int>
public static IList<int> SplitStringUsing(this string source, string seperator =",")
{
return source.Split(Convert.ToChar(seperator))
.Select(x => x.Trim())
.Where(x => !string.IsNullOrWhiteSpace(x))
.Select(int.Parse).ToList();
}
注意:以上代码尚未经过测试
我正在寻找像
这样的东西public static IList<T> SplitStringUsing(this string source, string seperator =",", T t)
{
find the type of t and convert it to respective List
}
答案 0 :(得分:8)
您可以使用Convert.ChangeType(object,string)解析System.Convert类支持的基类型,或实现IConvertible接口的任何其他类
public static IList<T> SplitStringUsing<T>(string source, string seperator = ",")
where T:IConvertible
{
return source.Split(Convert.ToChar(seperator))
.Where(x => !string.IsNullOrWhiteSpace(x))
.Select(x=>Convert.ChangeType(x,typeof(T)))
.Cast<T>()
.ToList();
}
为了避免本地化问题,您应该添加一个IFormatProvider参数,以允许调用者指定要使用的文化或默认使用当前文化,例如:
public static IList<T> SplitStringUsing<T>(string source,
string seperator = ",",
IFormatProvider provider =null)
where T:IConvertible
{
return source.Split(Convert.ToChar(seperator))
.Where(x => !string.IsNullOrWhiteSpace(x))
.Select(x=>Convert.ChangeType(x,typeof(T),provider))
.Cast<T>().ToList();
}
对于更通用的情况,您可以将解析代码作为lambda传递给函数:
public static IList<T> SplitStringUsing<T>(string source,
Func<string,T> parser,
string seperator = ",")
{
return source.Split(Convert.ToChar(seperator))
.Where(x => !string.IsNullOrWhiteSpace(x))
.Select(parser)
.ToList();
}
并将其称为:
var l1 = SplitStringUsing(x,s=>double.Parse(s,NumberStyles.HexNumber,
CultureInfo.InvariantCulture));
您可以在代码中使用这两种方法,编译器将选择正确的重载。
答案 1 :(得分:1)
我认为你需要Convert.ChangeType,就像这样。它没有经过全面测试,编译和修复。
public static IList<T> SplitStringUsing(string source, string seperator =",")
{
return source.Split(Convert.ToChar(seperator))
.Select(x => x.Trim())
.Where(x => !string.IsNullOrWhiteSpace(x))
.Select((T)Convert.ChangeType( x, typeof( T ) )).ToList();
}
答案 2 :(得分:0)
我想延长@PanagiotisKanavos的answer。
特别是通用方法:
public static class StringToListExtension
{
//see https://msdn.microsoft.com/en-us/library/System.String.Split.aspx
//and https://msdn.microsoft.com/en-us/library/bb548891.aspx
//this is the generic approach offering enough possibilies to use
public static IEnumerable<TResult> MapStringValues<TResult>(this String source, Func<String, TResult> itemMapper, String[] separator, StringSplitOptions options)
{
if (null == source) throw new ArgumentNullException("source");
return source.Split(separator, options).Select(itemMapper);
}
//add your implementation using MapStringValues<T>
public static IList<Int32> MapToInt32ListUsingParse(this String source, String[] separator, StringSplitOptions options)
{
return MapStringValues<Int32>(source, Int32.Parse, separator, options).ToList();
}
//or more convenient
public static IList<Int32> DefaultMapToIntList(this String source)
{
return MapStringValues<Int32>(source, Int32.Parse, DefaultSeparator, StringSplitOptions.RemoveEmptyEntries).ToList();
}
private static readonly String[] DefaultSeparator = new []{ "," };
}
您将使用该代码:
String values = "some,text,with,commas";
List<String> l1 = values.MapStringValues<String>(s => s, new []{ "," }, StringSplitOptions.None).ToList();
values = "2,4,,5,6";
IList<Int32> l2 = values.MapToInt32ListUsingParse(new []{ "," }, StringSplitOptions.RemoveEmptyEntries);
values = "2,4,,5,6";
IList<Int32> l3 = values.DefaultMapToIntList();
您可以为所有String to T案例添加便利实现。如果您不想抛出异常,只需使用Int32.TryParse等实现解析函数。