C# 覆盖 List<MyClass> 的 ToString()

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1340128/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 15:20:24  来源:igfitidea点击:

Overriding ToString() of List<MyClass>

c#stringextension-methodsoverridingtostring

提问by Bruno Reis

I have a class MyClass, and I would like to override the method ToString() of instances of List:

我有一个类 MyClass,我想覆盖 List 实例的 ToString() 方法:

class MyClass
{
    public string Property1 { get; set; }
    public int Property2 { get; set; }
    /* ... */
    public override string ToString()
    {
        return Property1.ToString() + "-" + Property2.ToString();
    }
}

I would like to have the following:

我想要以下内容:

var list = new List<MyClass>
            {
                new MyClass { Property1 = "A", Property2 = 1 },
                new MyClass { Property1 = "Z", Property2 = 2 },
            };

Console.WriteLine(list.ToString());   /* prints: A-1,Z-2 */

Is it possible to do so? Or I would have to subclass List<MyClass> to override the method ToString() in my subclass? Can I solve this problem using extension methods (ie, is it possible to override a method with an extension method)?

有可能这样做吗?或者我必须继承 List<MyClass> 来覆盖我的子类中的 ToString() 方法?我可以使用扩展方法解决这个问题吗(即,是否可以用扩展方法覆盖一个方法)?

Thanks!

谢谢!

采纳答案by Martin Harris

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:

您需要子类化以覆盖任何方法。泛型的重点是说无论 T 的类型如何,您都想要相同的行为。

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...

我仍然认为你最好子类化......

回答by Robban

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

您必须创建自己的自定义类,该类继承自 Collection,然后专门覆盖该类的 ToString() 方法。

回答by Bojan Resnik

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

如果必须命名方法,则必须ToStringList. 您可以将其设为通用:

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

In this case, you would have to use MyListinstead of Listthroughout your application if you wish to have your custom conversion.

在这种情况下,如果您希望进行自定义转换,则必须在整个应用程序中使用MyList而不是List

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:

您可以在任何实例上使用它,IEnumerable<T>就像它是一个普通方法一样:

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

回答by James

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

不,这是不可能的。TList 的 ToString 将为您提供列表对象的字符串表示形式。

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.
  • 从 TList 派生并覆盖您提到的 .ToString() 方法。(在这个例子中,我不会说它值得这样做)
  • 创建一个辅助方法,将 TList 列表转换为逗号分隔的字符串,例如扩展方法(可能是最好的建议)
  • 在 Console.WriteLine 阶段使用 foreach 语句。

Hope that helps!

希望有帮助!

回答by LukeH

Perhaps a bit off-topic, but I use a ToDelimitedStringextension 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:

也许有点题外话,但我使用了ToDelimitedString一种适用于任何IEnumerable<T>. 您可以(可选)指定要使用的分隔符和一个委托来为每个元素执行自定义字符串转换:

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

回答by peSHIr

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 TypeConverterimplementations.

根据您想要覆盖List<T>.ToString()以返回特定内容的确切原因,查看自定义TypeConverter实现可能会很方便。

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

如果您只是希望 a List<T>of specific在使用 TypeConverters 的位置(例如在调试器或类型情况下)T以某种方式显示为 a ,这可能就足够了。stringstring.Format("List: {0}", listVariable)

You might just have seen the result of ToString() being shown somewhere and wanted to change that, without knowing about the existence of TypeConverterand 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.

您可能刚刚看到 ToString() 的结果显示在某处并想要更改它,而不知道TypeConverter它们的存在和使用位置。我相信 .NET Framework 中的许多/大多数/所有(不确定是哪个?)默认 TypeConverters 在将它们定义的任何类型转换为string.

回答by Richard Lee

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

您实际上可以使用 unicode 技巧来允许您直接针对通用列表定义备用 ToString 方法。

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)

如果您在 Visual Studio 中启用十六进制字符输入,那么您可以通过按住 Alt 键创建不可见字符,然后在数字小键盘上按以下键 + FFF 9(现在释放 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#)

所以我们可以创建下面的函数,在它的名字旁边放一个不可见的字符......(是的,我知道它的 VB 代码,但这个概念仍然适用于 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.

现在在 Visual Studio 中,当您根据列表访问智能感知时,您将能够在标准 ToString 或自定义函数之间进行选择。



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

要在 Visual Studio 中启用十六进制字符输入,您可能需要编辑注册表

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

打开 HKEY_CURRENT_USER\Control Panel\Input Method 并创建一个名为 EnableHexNumpad 的 REG_SZ 将其设置为 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 &

您还需要禁用“文件”、“编辑”、“调试”、“数据”菜单的 & 快捷方式,在 Visual Studio 中,打开工具菜单,选择自定义,然后打开命令选项卡,并对使用的任何菜单项使用修改选择按钮通过删除 &

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

否则,您最终将打开弹出菜单,而不是键入十六进制字符。