覆盖List 的ToString()

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

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

我想要以下内容:

 var list = new List { new MyClass { Property1 = "A", Property2 = 1 }, new MyClass { Property1 = "Z", Property2 = 2 }, }; Console.WriteLine(list.ToString()); /* prints: A-1,Z-2 */ 

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

谢谢!

您需要子类来覆盖任何方法。 generics的意思是说你想要相同的行为而不管T的类型。如果你想要特定类型的T的不同行为,那么你打破了这个合约并且需要编写你自己的类:

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

编辑添加:

不,您不能通过创建扩展来覆盖方法,但您可以使用特定于此列表类型的不同签名创建新方法:

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

用于

 List myClassList = new List string output = myClassList.ExtendedToString(); 

我仍然认为你的子类化更好…

也许有点偏离主题,但我使用ToDelimitedString扩展方法,适用于任何IEnumerable 。 您可以(可选)指定要使用的分隔符,并使用委托为每个元素执行自定义字符串转换:

 // 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(this IEnumerable source) { return source.ToDelimitedString(x => x.ToString(), CultureInfo.CurrentCulture.TextInfo.ListSeparator); } public static string ToDelimitedString( this IEnumerable source, Func converter) { return source.ToDelimitedString(converter, CultureInfo.CurrentCulture.TextInfo.ListSeparator); } public static string ToDelimitedString( this IEnumerable source, string separator) { return source.ToDelimitedString(x => x.ToString(), separator); } public static string ToDelimitedString(this IEnumerable source, Func converter, string separator) { return string.Join(separator, source.Select(converter).ToArray()); } } 

如果您的方法必须命名为ToString ,则必须从List派生一个类。 你可以把它变成通用的:

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

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

但是,如果您可以为方法选择其他名称,则可以使用扩展方法并获得相同的效果,几乎不需要修改代码:

您可以使用扩展方法使其更通用:

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

你可以在IEnumerable任何实例上使用它,就好像它是一个普通的方法:

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

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

如果在visual studio中启用hex字符输入,则可以通过按住Alt键创建不可见字符,然后在数字键盘上按下以下键+ FFF 9(现在释放Alt)

所以我们可以创建以下函数,并在其名称旁边放置一个不可见的字符…(是的,我知道它的VB代码,但这个概念仍适用于C#)

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

现在在visual studio中,当您对列表访问intellisense时,您可以在标准ToString或自定义函数之间进行选择。


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

打开HKEY_CURRENT_USER \ Control Panel \ Input Method并创建一个名为EnableHexNumpad的REG_SZ,将其设置为1

您还需要禁用文件,编辑,调试,数据菜单和快捷方式,在Visual Studio中,打开工具菜单,选择自定义,然后打开命令选项卡,并使用任何菜单项的修改选择按钮其中任何一个ABCDEF特征为捷径,删除&

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

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

不可能。 TList的ToString将为您提供列表对象的字符串表示forms。

你的选择是:

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

希望有所帮助!

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

如果您只是希望特定TList在使用TypeConverters的位置以某种方式显示自己,就像在调试器或string.Format("List: {0}", listVariable)类型情况中一样,这可能就足够了。

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