2009-08-27 9 views
18

私はMyClassクラスを持っている、と私はリストのインスタンスのメソッドToString()をオーバーライドしたいと思います:オーバーライドToStringメソッド()は<MyClass>

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をサブクラス化する必要がありますか?拡張メソッドを使用してこの問題を解決できますか(つまり、メソッドを拡張メソッドでオーバーライドすることは可能ですか)

ありがとうございます!

+0

詳細については、私はNHibernateに関連する何かをしようとしていました、そして、コレクションのマッピングを、単一の列に収まるシリアライズされた文字列で行いました。しかし、自分のIUserTypeを実装することで、別の方法でそれを行うことができました。私の実装では、必要に応じて文字列を作成します。とにかく返事をいただいた皆さん、ありがとうございます! –

答えて

21

任意のメソッドをオーバーライドするには、サブクラス化する必要があります。ジェネリックのポイントは、Tのタイプにかかわらず同じ振る舞いを望むと言うことです。あなたが特定のタイプのTに違った振る舞いをしたいのであれば、あなたはその契約を破っており、あなた自身のクラスを書く必要があります:

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

編集追加する:

をいいえ、あなたは拡張子を作成することによって、メソッドをオーバーライドすることはできませんが、このリストのタイプに固有の異なる署名で新しいメソッドを作成することができます。

public static string ExtendedToString(this List<MyClass> list) 
{ 
    return .... 
} 
あなたはCollectionから継承する独自のカスタムクラスを作成し、その後のToStringメソッド()メソッドoverwrideしなければならない、私はまだあなたががサブクラス化ほうだと思う

で使用さ

...

+1

これは新しいリストクラスのコードなので、 'MyClass'クラスと同じコードファイルの上に追加します。だからこれは非常に余分な努力ではなく、たとえ新しいクラスを作成するのが複雑であっても、ほとんどの機能が 'List'クラスから継承されているからです。 – awe

+0

**エクステンションについてメソッド:** この場合、 'ToString'メソッドは論理的にあなたが望むものであり、' List'はそれの有用なデフォルトの実装を持たないので、サブクラス化を行うべきであることに私は同意します。 Extensionは新しいメソッドを追加して、 'ToString'メソッドを汎用の' List'クラスのためのものと同じくらい役に立たないままにします。 – awe

0

そのクラスは特に。

2

あなたの方法は、あなたがListからクラスを派生する必要がありますToString名前を付ける必要があります。あなたは一般的なことを行うことができます。

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

、あなたがあなたのカスタム変換を希望する場合は、アプリケーション全体でMyListの代わりListを使用しなければならないでしょう。

あなたのメソッドのために別の名前を選択することができますしかし、もし、あなたが拡張メソッドを使用して同じ効果を得ることができ、あなたのコードにほとんど変更を加えた:

あなたは、これはより汎用的にするために拡張メソッドを使用することができます:

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

ませんそのないP:

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

あなたはそれが通常の方法であるかのようIEnumerable<T>の任意のインスタンス上でそれを使用することができますオッシブル。 ToString of TListは、リストオブジェクトの文字列表現を提供します。

あなたのオプションは以下のとおりです。

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

希望に役立ちます!

21

多分少し話題はありませんが、私はのために働くToDelimitedString拡張メソッドを使用します。それは便利かもしれない特定の何かを返すようにList<T>.ToString()を上書きする

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

一般的に良い提案:私は自分自身もそのような拡張メソッドを使用します。元の質問の正確な文脈に応じて、これは有効な答えかもしれません。 – peSHIr

+0

これは本当に便利な拡張メソッドです、ありがとう! 匿名列挙型のIListを使用して関数を読み込んで、コンバータのパラメータとして使用された(x =>((short)Convert.ChangeType(x、TypeCode.Int16))カンマ区切りリストに変換するのを手伝ってくれました。再びLuke –

+0

danrichardsonのコメントによると、入力のおかげでこれは非常に便利です! –

0

あなたが望むのために持っている正確な理由に応じて:あなたは(必要に応じて)各要素のカスタム文字列の変換を実行するために使用する区切り文字とデリゲートを指定することができますカスタムTypeConverterの実装を見てください。

あなたは、単に特定のTList<T>は、デバッガやstring.Format("List: {0}", listVariable)タイプの状況のように、これは十分かもしれないが、それ自体がTypeConvertersが使用されている場所でstringなどの特定の方法を表示したい場合。

TypeConverterの存在とそれらが使用されている場所を知らなくても、ToString()の結果がどこかに表示されていて、それを変更したかったかもしれません。 .NET Frameworkの既定のTypeConvertersの多く/ほとんど/すべて(どちらが確実かわからない)は、定義されている任意の型をstringに変換するときにToString()を使用すると考えています。

2

実際には、ユニコードのトリックを使用して、ジェネリックリストに対して直接代替ToStringメソッドを定義することができます。

あなたは、Visual Studioに進文字入力を有効にした場合、あなたは、あなたのテンキー+ FFF 9上で、次のキーを押し、Altキーを押しながら目に見えない文字を作成することができますが(今Altキーを離す)

だから我々は、作成することができますVisual Studioで今、その名前の隣に配置見えない文字と、次の関数...(はい私はそのVBのコードを知っているが、概念はまだC#のための作業を動作します)

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

、あなたは反対インテリセンスアクセス標準のToStringまたはカスタム関数のいずれかを選択することができます。あなたがあなたのレジストリ

オープンHKEY_CURRENT_USER \コントロールパネル\を入力する方法 を編集し、REG_SZを作成する必要があり


の視覚スタジオに進文字入力を有効にするには、EnableHexNumpadが1

にあなたをこのセットと呼ばれますファイル、編集、デバッグ、データメニューの&ショートカットも無効にする必要があります。ビジュアルスタジオでは、ツールメニューを開き、カスタマイズを選択し、コマンドタブを開き、使用するメニュー項目に選択変更ボタンを使用します。 ABCDEFのいずれか&

そうしないと、16進文字を入力する代わりにポップアップメニューが表示されます。

+0

これはうんざりしており、あなたの答えはすべての永遠のために削除されるはずです... +1 –

+1

Idkは動作しますが、キックル!+1 –

関連する問題