Overriding ToString() of List<MyClass>

烈酒焚心 提交于 2019-11-28 21:17:06

You'll need to subclass to override any method. The point of generics is to say that you want the same behaviour regardless of the type of T. If you want different behaviour for a specific type of T then you are breaking that contract and will need to write your own class:

public class MyTypeList : List<MyClass>
{
    public override string ToString()
    {
        return ...
    }
}

Edited to add:

No, you can't override a method by creating an extension, but you could create a new method with a different signature that is specific to this list type:

public static string ExtendedToString(this List<MyClass> list)
{
     return ....
} 

Used with

List<MyClass> myClassList = new List<MyClass>
string output = myClassList.ExtendedToString();

I still think you're better off subclassing though...

Perhaps a bit off-topic, but I use a ToDelimitedString extension method which works for any IEnumerable<T>. You can (optionally) specify the delimiter to use and a delegate to perform a custom string conversion for each element:

// if you've already overridden ToString in your MyClass object...
Console.WriteLine(list.ToDelimitedString());
// if you don't have a custom ToString method in your MyClass object...
Console.WriteLine(list.ToDelimitedString(x => x.Property1 + "-" + x.Property2));

// ...

public static class MyExtensionMethods
{
    public static string ToDelimitedString<T>(this IEnumerable<T> source)
    {
        return source.ToDelimitedString(x => x.ToString(),
            CultureInfo.CurrentCulture.TextInfo.ListSeparator);
    }

    public static string ToDelimitedString<T>(
        this IEnumerable<T> source, Func<T, string> converter)
    {
        return source.ToDelimitedString(converter,
            CultureInfo.CurrentCulture.TextInfo.ListSeparator);
    }

    public static string ToDelimitedString<T>(
        this IEnumerable<T> source, string separator)
    {
        return source.ToDelimitedString(x => x.ToString(), separator);
    }

    public static string ToDelimitedString<T>(this IEnumerable<T> source,
        Func<T, string> converter, string separator)
    {
        return string.Join(separator, source.Select(converter).ToArray());
    }
}

You can actually use a unicode trick to allow you to define an alternate ToString method directly against your generic list.

If you enable hex character input into visual studio then you can create invisible characters by holding down the Alt key, then pressing the following on your numeric keypad + F F F 9 (now release Alt)

So we can create the following function with an invisible character placed next to its name... (yes i know its VB code, but the concept will still work work for C#)

<Extension()> _
Public Function ToString(ByVal source As Generic.List(Of Char)) As String
   Return String.Join(separator:="", values:=source.ToArray)
End Function

Now in visual studio, when you access intellisense against your list, you will be able to choose between either the standard ToString or your custom function.


To enable hex character input into visual studio you may need to edit your registry

open HKEY_CURRENT_USER\Control Panel\Input Method and create a REG_SZ called EnableHexNumpad set this to 1

You will also need to disable the & shortcuts for the File, Edit, Debug, Data menus, In visual studio, open the tools menu, select customize, then open the commands tab, and using the modify selection button for any menu item that uses either of the ABCDEF charactes for its short cut, by removing the &

Otherwise you will end up opening popup menus, instead of typing hex characters.

If you method must be named ToString you will have to derive a class from List. You can make it a generic:

static class MyList<T> : List<T>
{
    public override string ToString()
    {
        // ...
    }
}

In this case, you would have to use MyList instead of List throughout your application if you wish to have your custom conversion.

However, if you can choose a different name for your method, you can use extension methods and achieve the same effect, with almost no modifications to your code:

You can use extension methods to make this more generic:

static class ListExtension
{
    public static void ConvertToString<T>(this IEnumerable<T> items)
    {
        // ...
    }
}

You can use it on any instance of IEnumerable<T> just as if it were an ordinary method:

List<MyClass> list = new List<MyClass> { ... };
Console.WriteLine(list.ConvertToString());

int[] array_of_ints = {1,2,3,4,5};
Console.WriteLine(array_of_ints.ConvertToString());

You would have to create your own custom class that inherits from Collection and then overwride the ToString() method of that class specifically.

No its not possible. ToString of TList will give you the string representation of the list object.

Your options are:

  • Derive from TList and override the .ToString() method as you mentioned. (in this example I wouldn't say its worth doing so)
  • Create a helper method that converts a TList list to a comma delimited string e.g. extension method (probably best suggestion)
  • Use a foreach statement at the Console.WriteLine stage.

Hope that helps!

Depending on the exact reason you have for wanting to override List<T>.ToString() to return something specific it might be handy to have a look at custom TypeConverter implementations.

If you simply want a List<T> of specific T to show itself a certain way as a string in locations where TypeConverters are used, like in the debugger or in string.Format("List: {0}", listVariable) type situations, this might be enough.

You might just have seen the result of ToString() being shown somewhere and wanted to change that, without knowing about the existence of TypeConverter and locations where they are used. I believe many/most/all (not sure which?) of the default TypeConverters in the .NET Framework simply use ToString() when converting any type for which they are defined for to a string.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!