Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Extension Method Overload

I have two extension methods:

    public static string ToString(this List<object> list, char delimiter)
    {
        return ToString<object>(list, delimiter.ToString());
    }

    public static string ToString(this List<object> list, string delimiter)
    {
        return ToString<object>(list, delimiter);
    }

When I use this:

    char delimiter = ' ';
    return tokens.ToString(delimiter);

It won't work. The char overload doesn't show up in the code completion list either. Can anybody tell me how to make this work?

EDIT

I accidentally forgot to mention that there are in fact 3 extension methods, the third being:

    public static string ToString<T>(this List<T> list, string delimiter)
    {
        if (list.Count > 0)
        {
            string s = list[0].ToString();

            for (int i = 1; i < list.Count; i++)
                s += delimiter + list[i].ToString();

            return s;
        }

        return "";
    }
like image 572
Thick_propheT Avatar asked Sep 08 '26 18:09

Thick_propheT


2 Answers

Add reference to the class in which you have the extension methods:

using MyApplicationNamespace.ToStringExtensionClass;

VS / ReSharper doesn't offer to add reference automatically simply because the method is already recognized, just not with that particular signature.

Also, your methods themselves don't compile unless you have a third extension methods with generic parameter.

The way they work for me (compile and logically):

public static string ToString(this List<object> list, char delimiter)
{
    return ToString(list, delimiter.ToString());
}

public static string ToString(this List<object> list, string delimiter)
{
    return string.Join(delimiter, list);
}

Usage will then be:

var list = new List<int> { 1, 2, 3, 4, 5 };
var str = list.Cast<object>().ToList().ToString(' ');

If you want to avoid casting and make the methods generic, change them to:

public static string ToString<T>(this List<T> list, char delimiter)
{
    return ToString(list, delimiter.ToString());
}

public static string ToString<T>(this List<T> list, string delimiter)
{
    return string.Join(delimiter, list);
}

And then the usage is much cleaner:

var list = new List<int> { 1, 2, 3, 4, 5 };
var str = list.ToString(' ');

EDIT

So after your edit I understand your problem better. You should lose the non-generic methods and have generic overload to accept char as well.

public static string ToString<T>(this List<T> list, char delimiter)
{
    return ToString(list, delimiter.ToString());
}

public static string ToString<T>(this List<T> list, string delimiter)
{
    ...
}

Also, the logic you are trying to implement can be easily achieved with:

string.Join(delimiter, list);

So you can basically delete all of those methods and just use that, unless you really want it as an extension method for lists.

like image 137
SimpleVar Avatar answered Sep 11 '26 07:09

SimpleVar


I think your problem is that you are specifying the type of object for your generic List and not making it a generic method.

See if it works when you define something like the following:

public static string ToString<T>(this List<T> list, char delimiter) 
{ 
    return ToString<T>(list, delimiter.ToString()); 
} 

public static string ToString<T>(this List<T> list, string delimiter) 
{ 
    return String.join(list, delimiter); 
} 

Your original function with the string delimiter was just calling itself so you'll have to change your ToString<T>(this List<T> list, string delimiter) to do something useful here like a String.join

like image 24
nvuono Avatar answered Sep 11 '26 08:09

nvuono



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!