1

I have code that I want to make the following changes:

  1. How do I override ToString()? It says: A static member ...ToString(System.Collections.Generic.List)' cannot be marked as override, virtual, or abstract.

  2. How do I make it generic?

    public static override string ToString(this List<int> list) {
        string output = "";
        list.ForEach(item => output += item.ToString() + "," );
        return output;
    }
    

Thanks!

B Seven
  • 44,484
  • 66
  • 240
  • 385

4 Answers4

5

You cannot use extension methods to override an existing method.

From the spec http://msdn.microsoft.com/en-us/library/bb383977.aspx

"You can use extension methods to extend a class or interface, but not to override them. An extension method with the same name and signature as an interface or class method will never be called. At compile time, extension methods always have lower priority than instance methods defined in the type itself."

Michael Gattuso
  • 13,020
  • 2
  • 25
  • 29
5

If you want to override ToString(), you would need to inherit from List<T> rather than try to extend it. You have already seen that you cannot mark the static extension method as override, and overload resolution will always go for the member method over an extension method if it is available. Your options are

  • Inherit and override
  • Change your extension method's name to something else ToSpecialString()
  • Call the method directly using the class name MyExtensions.ToString(myList);
Anthony Pegram
  • 123,721
  • 27
  • 225
  • 246
3

What are you trying to achieve? Often I want to output the contents of a list, so I created the following extension method:

public static string Join(this IEnumerable<string> strings, string seperator)
{
    return string.Join(seperator, strings.ToArray());
}

It is then consumed like this

var output = list.Select(a.ToString()).Join(",");

EDIT: To make it easier to use for non string lists, here is another variation of above

public static String Join<T>(this IEnumerable<T> enumerable, string seperator)
{
    var nullRepresentation = "";
    var enumerableAsStrings = enumerable.Select(a => a == null ? nullRepresentation : a.ToString()).ToArray();
    return string.Join(seperator, enumerableAsStrings);
}

public static String Join<T>(this IEnumerable<T> enumerable)
{
    return enumerable.Join(",");
}

Now you can consume it like this

int[] list = {1,2,3,4};
Console.WriteLine(list.Join()); // 1,2,3,4
Console.WriteLine(list.Join(", ")); // 1, 2, 3, 4
Console.WriteLine(list.Select(a=>a+".0").Join()); // 1.0, 2.0, 3.0, 4.0
Iain
  • 10,814
  • 3
  • 36
  • 31
  • Given a list of { 5, 10, 20 }, I want to get the string "5,10,20". And, I want it to work for many data types such as int, double, string, bool, etc. – B Seven Nov 04 '10 at 05:13
  • I added a new variation of the Join method that better suits your needs. Overall I found it to be quite a useful method in unit tests and when debugging. You can also use "\n" as the separator to get each list item onto a new line. – Iain Nov 04 '10 at 06:12
1

You can only override a method if you inherit the base class.

What I would advocate is calling your extension method .ToCsv().

Alastair Pitts
  • 19,423
  • 9
  • 68
  • 97