我有一个MyClass类,我想重写名单的实例的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<MyClass>
{
new MyClass { Property1 = "A", Property2 = 1 },
new MyClass { Property1 = "Z", Property2 = 2 },
};
Console.WriteLine(list.ToString()); /* prints: A-1,Z-2 */
是否可以这样做呢? 或者我会继承名单<MyClass的>覆盖在我的子类的toString()方法? 我能解决使用扩展方法(即,它可以覆盖与扩展方法的方法)这个问题呢?
谢谢!
Answer 1:
你需要继承覆盖任何方法。 泛型的一点是说,你要相同的行为,无论T的类型,如果你想为一个特定的类型T,那么你打破了合同,需要编写自己的类的不同的行为:
public class MyTypeList : List<MyClass>
{
public override string ToString()
{
return ...
}
}
编辑补充:
不,你不能创建一个扩展覆盖的方法,但你可以创建不同的签名特定于该列表类型的新方法:
public static string ExtendedToString(this List<MyClass> list)
{
return ....
}
使用
List<MyClass> myClassList = new List<MyClass>
string output = myClassList.ExtendedToString();
我仍然认为你有了更好的子类,虽然...
Answer 2:
或许有点偏离主题,但我用一个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());
}
}
Answer 3:
实际上,你可以使用Unicode窍门,让你直接对您的泛型列表定义备用ToString方法。
如果启用十六进制字符输入到Visual Studio,那么你可以按住Alt键,然后按数字键盘上下面创建不可见的字符+ FFF 9(现在放开Alt键)
因此,我们可以放在旁边的名称中不可见的字符创建下面的函数...(是的,我知道它的VB代码,但概念仍然适用于C#的工作)
<Extension()> _
Public Function ToString(ByVal source As Generic.List(Of Char)) As String
Return String.Join(separator:="", values:=source.ToArray)
End Function
现在,在Visual Studio中,当您访问智能感知的与你,你就可以无论是标准的ToString或您的自定义功能之间进行选择。
要启用十六进制字符输入到Visual Studio中,你可能需要修改你的注册表
打开HKEY_CURRENT_USER \控制面板\输入法,并创建一个名为EnableHexNumpad REG_SZ将其设置为1
您还需要禁用和快捷方式的文件,编辑,调试,数据的菜单,在Visual Studio中,打开工具菜单,选择自定义,然后打开命令选项卡,并使用修改选择按钮使用任何菜单项无论是ABCDEF本地字符对于其短切的,通过去除与
否则,你最终会打开弹出菜单,而不是键入十六进制字符。
Answer 4:
如果你的方法必须命名ToString
你将不得不从派生类List
。 你可以把它一个通用的:
static class MyList<T> : List<T>
{
public override string ToString()
{
// ...
}
}
在这种情况下,你将不得不使用MyList
而不是List
,如果您希望您的自定义转换整个应用程序。
但是,如果你能为你的方法选择不同的名称,则可以使用扩展方法,达到同样的效果,几乎没有修改你的代码:
您可以使用扩展方法,使这个更通用的:
static class ListExtension
{
public static void ConvertToString<T>(this IEnumerable<T> items)
{
// ...
}
}
你可以用它在任何情况下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());
Answer 5:
你将不得不创建一个从集合,然后overwride该类的ToString()方法具体继承自己的自定义类。
Answer 6:
没有它不可能。 从TList的ToString会给你的列表对象的字符串表示。
你的选择是:
- 从从TList派生和你所提到的覆盖的ToString()方法。 (在这个例子中,我不会说,它值得这样做)
- 创建一个列表的TList转换为逗号分隔的字符串如扩展方法(可能是最好的建议)一个辅助方法
- 在Console.WriteLine命令阶段使用foreach语句。
希望帮助!
Answer 7:
根据您有想要覆盖的确切原因List<T>.ToString()
返回特定的东西可能是很方便的看一下自定义TypeConverter
实现。
如果只想一个List<T>
特定的T
到本身表现出一定的方式作为一个string
中的位置,其中类型转换器的使用,像在调试器或在string.Format("List: {0}", listVariable)
型的情况下,这可能是不够的。
你可能只是看到的ToString()的结果所显示的地方,想改变这种状况,不知道对存在TypeConverter
在那里它们被使用和位置。 我相信很多/大部分/所有在.NET Framework的默认类型转换器的(不知道哪一个?)简单地使用的ToString转换为它们的一个定义的任何类型时,() string
。
文章来源: Overriding ToString() of List