Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I write a generic extension method for converting a delimited string to a list?

We often have a need to turn a string with values separated by some character into a list. I want to write a generic extension method that will turn the string into a list of a specified type. Here is what I have so far:

    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();
    }

But I get an error.

Cannot convert type 'string' to type 'T'.

Is there a better way to do this or do I need to create multiple extension methods for the different types of lists and do Convert.ToInt32(), etc?

UPDATE

I'm trying to do things like this:

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

or

var someStr = "true;false;true;true;false";
List<bool> boolList = someStr.ToDelimitedList<bool>(";");
like image 433
Chev Avatar asked Mar 18 '13 16:03

Chev


People also ask

How to define extension method in C#?

Extension methods are defined as static methods but are called by using instance method syntax. Their first parameter specifies which type the method operates on. The parameter is preceded by the this modifier.

What are extension methods in C# explain with example?

In C#, the extension method concept allows you to add new methods in the existing class or in the structure without modifying the source code of the original type and you do not require any kind of special permission from the original type and there is no need to re-compile the original type.

How can I convert comma separated string into a list string C#?

To convert a delimited string to a sequence of strings in C#, you can use the String. Split() method. Since the Split() method returns a string array, you can convert it into a List using the ToList() method.


4 Answers

Convert.ChangeType will work for primitive and many framework types (assuming default parsing rules are good enough):

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

If you need this to work for your own custom types, you'll have to get them to implement the IConvertible interface.

Do bear in mind that this isn't sophisticated enough to work with custom conversion rules or robust enough to deal with failure properly (beyond throwing an exception and making the entire operation fail). If you need support for this, provide an overload that accepts a TypeConverter or conversion delegate (as in mike z's answer).

like image 152
Ani Avatar answered Sep 23 '22 03:09

Ani


There is no built in way to convert a string to an arbitrary type T. Your method would have to take some kind of delegate:

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();
}
like image 37
Mike Zboray Avatar answered Sep 24 '22 03:09

Mike Zboray


Seems like you could just use String.Split and Enumerable.Select?

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

But if you must make an extension, try this...

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));
like image 23
p.s.w.g Avatar answered Sep 22 '22 03:09

p.s.w.g


Is this not a perfect task for LINQ?

You could just do something like the following:

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

You can alter the generic Select() delegate depending on your situation.

like image 24
Oliver Avatar answered Sep 24 '22 03:09

Oliver