代码之家  ›  专栏  ›  技术社区  ›  Bruno Reis

重写列表的ToString()<MyClass>

  •  20
  • Bruno Reis  · 技术社区  · 15 年前

    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 */
    

    有可能吗?或者,我将不得不对List进行子类化<MyClass>在我的子类中重写ToString()方法?我可以使用扩展方法解决这个问题吗(即,是否可以用扩展方法重写方法)?

    谢谢

    7 回复  |  直到 15 年前
        1
  •  29
  •   LukeH    15 年前

    也许有点离题,但我用了 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());
        }
    }
    
        2
  •  25
  •   Martin Harris    11 年前

    您需要子类来重写任何方法。泛型的要点是,无论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();
    

        3
  •  3
  •   Richard Lee    10 年前

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

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

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


    若要将十六进制字符输入visual studio,您可能需要编辑注册表

    打开HKEY\u当前用户\控制面板\输入法 并创建一个名为EnableHexNumpad的注册表项,将其设置为1

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

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

        4
  •  2
  •   Bojan Resnik    15 年前

    ToString 您必须从中派生一个类 List . 您可以将其设置为通用:

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

    在这种情况下,您必须使用 MyList 而不是 列表

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

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

    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());
    
        5
  •  0
  •   Robban    15 年前

        6
  •  0
  •   James    15 年前

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

    你的选择是:

    • 在Console.WriteLine阶段使用foreach语句。

    希望有帮助!

        7
  •  0
  •   peSHIr    15 年前

    取决于您想要覆盖的确切原因 List<T>.ToString() 要返回特定的内容,可以方便地查看custom TypeConverter 实现。

    List<T> 特定的 T 以某种方式显示自己作为一个 string 在使用类型转换器的位置,如调试器或 string.Format("List: {0}", listVariable) 输入情况,这可能就足够了。

    类型转换器 以及使用它们的位置。我相信.NET Framework中的许多/大多数/所有(不确定是哪一个?)默认类型转换器在将其定义的任何类型转换为 一串 .