27

クラス 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<MyClass>
            {
                new MyClass { Property1 = "A", Property2 = 1 },
                new MyClass { Property1 = "Z", Property2 = 2 },
            };

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

そうすることは可能ですか?または、サブクラスでメソッド ToString() をオーバーライドするには、List<MyClass> をサブクラス化する必要がありますか? 拡張メソッドを使用してこの問題を解決できますか (つまり、拡張メソッドでメソッドをオーバーライドできますか)?

ありがとう!

4

7 に答える 7

29

おそらく少し話題から外れていますが、私は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());
    }
}
于 2009-08-27T11:30:54.130 に答える
25

メソッドをオーバーライドするには、サブクラス化する必要があります。ジェネリックの要点は、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();

それでもサブクラス化したほうがいいと思うけど…

于 2009-08-27T10:21:58.417 に答える
2

メソッドに名前を付ける必要がある場合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());
于 2009-08-27T10:31:30.347 に答える
0

Collection から継承する独自のカスタム クラスを作成し、そのクラスの ToString() メソッドを具体的にオーバーライドする必要があります。

于 2009-08-27T10:23:25.917 に答える
0

いいえ、それは不可能です。TList の ToString は、リスト オブジェクトの文字列表現を提供します。

オプションは次のとおりです。

  • あなたが言及したように、 TList から派生させ、 .ToString() メソッドをオーバーライドします。(この例では、そうする価値があるとは言いません)
  • TList リストをカンマ区切りの文字列に変換するヘルパー メソッド (拡張メソッドなど) を作成します (おそらく最良の提案)。
  • Console.WriteLine ステージで foreach ステートメントを使用します。

それが役立つことを願っています!

于 2009-08-27T10:33:59.063 に答える
0

List<T>.ToString()オーバーライドして特定のものを返したい正確な理由によっては、カスタムTypeConverter実装を確認すると便利な場合があります。

デバッガーや型の状況など、TypeConverters が使用されている場所でList<T>特定Tの を特定の方法で表示したいだけの場合は、これで十分かもしれません。stringstring.Format("List: {0}", listVariable)

TypeConverterToString() の結果がどこかに表示されているのを見て、それらが使用されている場所やその存在を知らずに、それを変更したいと思ったかもしれません。.NET Framework の既定の TypeConverters の多く/ほとんど/すべて (どれかはわかりません) は、定義されている型を に変換するときに ToString() を使用するだけだと思いますstring

于 2009-08-27T11:54:25.190 に答える