逗号分隔字符串到通用列表

时间:2015-01-30 09:46:05

标签: c# string reflection collections

我能够将逗号分隔的字符串转换为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
}

3 个答案:

答案 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等实现解析函数。