0

リストに格納されている多くのクラスがあります。リストをジェネリック型として受け入れ、適切なリスト内のすべての要素の内容を文字列として返すメソッドを作成しようとしています。

これは多くのクラスの 1 つのサンプルです。これは List<Player> として定義されます。

public class Player
{
    public int PlayerId { get; set; }
    public string PlayerName { get; set; }
    public string FavoriteThing { get; set; }
}

ここで構文を正しくするのにまだ苦労しています:

  public static string GetStringOfData<T>(List<T> data)
    {
        string dataString = string.Empty;
        var type = data.GetType();

        // Insert magic here to get values for PlayerId, PlayerName, etc...

        return dataString;
    }

どうすればこれを実現できますか? 私はC#4.0を使用しています。

更新 私が使用しているクラスは、データベースに接続する edmx モデルから生成されます。これは、さまざまなテーブルを解析し、エラーを電子メールでユーザーに報告するレポート ツール用です。ユーザーは、すべてのフィールドの内容を表示する機能を具体的に要求しています。

4

5 に答える 5

5

ToStringすべての型はからメソッドを継承しobjectます。ToStringクラスでオーバーライドします。

public class Player
{
    ...
    public override string ToString()
    {
        return String.Format("Player [ID = {0}, Name = {1}]",
                             PlayerId, PlayerName);
    }

}

次に、非ジェネリックIEnumerableを使用してそれらに取り組むことができます。List<T>(で無料のランチを食べることができるのであれば、なぜ自分自身を制限するIEnumerableのですか? 後者はList<T>、 、配列、SortedLists<T>HashSet<T>、コレクションにまったく基づいていないIEnumerable<T>のアルゴリズム実装で動作します...)IEnumerable

public static string GetStringOfData(IEnumerable data)
{
    var sb = new StringBuilder();
        
    foreach (object o in data) {
        sb.Append(o).Append("; ");
    }    
    if (sb.Length >= 2 ) {
        sb.Length -= 2;
    }    
    return sb.ToString();
}

これは、ほぼすべてのタイプのコレクションで機能します。


注: オーバーライドToStringには、デバッガーが型名を表示するだけでなく、この文字列を表示するという肯定的な副作用があります。

于 2012-11-01T14:42:00.077 に答える
3

次のことができるはずです。

        foreach(T item in data)
        {
            var props = item.GetType().GetProperties();
            foreach(var prop in props)
            {   
                dataString += prop.GetValue(item, null);
            }
        }
于 2012-11-01T14:41:08.160 に答える
1

各クラスのオーバーライドToString()メソッドの最初:

public class Player
{
    public int PlayerId { get; set; }
    public string PlayerName { get; set; }
    public string FavoriteThing { get; set; }
    public override string ToString()
    {
        return this.PlayerId.Tostring() + " " + PlayerName + " " + FavoriteThing;
    }
}

次に、メソッドで、クラス インスタンスから返されたすべての文字列を連結します。

public static string GetStringOfData<T>(List<T> data)
        {
            StringBuilder dataBuilder = new StringBuilder();
            foreach (object o in data)
            {
                dataBuilder.Append(o.ToString());
                dataBuilder.Append(" ");
            }

            return dataBuilder.ToString();
        }

StringBuilderパフォーマンスの問題のため、を使用して文字列を連結することをお勧めします。

于 2012-11-01T14:43:57.857 に答える
1

ここにいくつかのオプションがあります。

すべてのクラスに、次のようなインターフェイスを実装させることができます

IDataString

これには、オブジェクトから文字列データを取得するメソッドが含まれています。次に、メソッドはそれらのリストを受け入れ、文字列を返すことができます:

public static string GetStringOfData(List<IDataString> data)
    {
        StringBuilder sb = new StringBuilder();
        foreach(var dm in data)
        {
          sb.append(dm.InterfaceMethod());
        }

        return sb.ToString()
    }

すべてのオブジェクトで ToString をオーバーライドし、オブジェクトのリストを受け入れることもできます。コードは似ています。これは、通常の ToString 機能を失うことを気にしないことを前提としています。

これは、質問で求めていることだと思いますが、すべてのパブリック文字列フィールドを連結するだけですか? これは少し遅く、より醜いですが、確かに可能です。

于 2012-11-01T14:41:04.983 に答える
0

あなたが期待している魔法はリフレクションかもしれません:実行時にプロパティを決定し、リスト内の各アイテムの値を取得します。

このためのコードは次のとおりです。

public static string GetStringOfData<T>(List<T> list)
{
    var stringBuilder = new StringBuilder();

    var properties = typeof(T).GetProperties()
        .Where(p => !p.GetIndexParameters().Any());

    foreach (var item in list)
    {
        foreach (var propertyInfo in properties)
        {
            stringBuilder.AppendFormat("{0}={1};",
                                        propertyInfo.Name,
                                        propertyInfo.GetValue(item, null));
        }
        stringBuilder.AppendLine();
    }

    return stringBuilder.ToString();
}
于 2012-11-01T14:45:06.510 に答える