-1

私はしばしばこのようなコードを持っています。

StringBuilder sb=new StringBuilder();
IEnumberable<MyWidget> MyWidgets=GetMyWidgets();
if(MyWidgets.Count!=0)
    {
    sb.Append("This is header text");
    foreach(MyWidget widget in MyWidgets)
        {
        sb.Append("This is info about widget: "+widget.SomeInfo);
        }
    sb.Append("This is footer text");
    }

これをきれいにする方法はありますか?おそらく、ラムダ式または匿名関数を使用していますか (私はそれらに慣れていないので、例が役に立ちます)?

オブジェクトのコレクションにアイテムが存在する場合の実際の例は、HTML テーブルを作成することです。

4

8 に答える 8

3

他の提案に加えて、Any代わりに使用することが重要ですCount

  if (MyWidgets.Any())
    {
        sb.Append("This is header text");
        sb.Append(string.Concat("", MyWidgets.Select(x => "This is info about widget: " + x.SomeInfo)));
        sb.Append("This is footer text");
    }

少量のデータの場合、元のバージョンの方が高速に動作します。私の場合、100 要素の場合は 2 倍高速でした。しかし、大量の場合、Linq の方が高速です。私の場合、100000 アイテムの選択で 10% です。どうしてそうなったかはわかりませんが、伯爵のせいです。

于 2013-05-23T16:39:04.573 に答える
1

を使用して、これらすべてを単一のステートメントに折りたたむことができますstring.Join

if(MyWidgets.Count() != 0) {
    sb.AppendFormat(
        "This is header text\n{0}This is footer text\n"
    ,   string.Join(
            "\n"
        ,   MyWidgets.Select(w => string.Format("This is info about widget: {0}\n", w))
        )
    );
}
于 2013-05-23T16:29:24.837 に答える
1

string.Joina を使用すると可読性が向上すると思います。これにより、多くの追加を行う必要がなくなるため、単純な文字列連結で問題ありません。

string str = "";
IEnumerable<MyWidget> MyWidgets=GetMyWidgets();
if(MyWidgets.Any())
{
    str += "This is header text\n";
    str += string.Join("\n", MyWidgets.Select(x => "This is info about widget: "
                                                   + x.SomeInfo));
    str += "\nThis is footer text";
}
于 2013-05-23T16:44:03.833 に答える
1

このコードには、他の種類の実装は必要ありません。

コードはそのままで十分にきれいで、意図は完全に明確です。

@RyanWH は次のように付け加えます。

このような状況で LINQ を使用すると、必要なパフォーマンスの向上が得られる場合にのみ、LINQ を使用することをお勧めします。ただし、元の質問は速度に関係していなかったので、元のコンテンツがシンプルで理解しやすいことに同意します。

于 2013-05-23T16:28:06.923 に答える
0

個人的にやりたい変更点は以上です。私の意見では、すべてを LINQ で識別しようとするよりも、プライベート メソッドの方がはるかに表現力があると思います。また、保守性を高めるために、定数のハードコードされた値を変更することも検討します。

public string YourMethod()
{
    string text = string.Empty;
    IEnumberable<MyWidget> MyWidgets = GetMyWidgets();

    if(MyWidgets.Any())
    {
        text += "This is header text";
        text +=  GetInfoFromWidgets(MyWidgets);
        text += "This is footer text";
    }

    return text;
}

private string GetInfoFromWidgets(IEnumerable<MyWidget> widgets)
{
    StringBuilder sb = new StringBuilder();
    foreach(MyWidget widget in MyWidgets)
    {
        sb.Append("This is info about widget: "+widget.SomeInfo);
    }
    return sb.ToString();
}
于 2013-05-23T16:51:16.927 に答える
0

そこにあるものを正確に関数に入れるのはどうですか?その実装には何も問題はなく、いかなる意味でも「汚い」わけではありません。コードをより少ない行に置くことは、必ずしもより良いことを意味するわけではありません。一般的な項目の一般的なコレクションを入力パラメーターとして使用し、文字列ビルダーを返すことができます。このような単純なルーチンの行数を最小限に抑えるよりも、プロジェクト内のコピーペーストされたコードを削除する方がはるかに優れています。

XML または HTML のシリアル化を行う可能性について話している場合は、それを行うツールが既に用意されています。C# は、XML に何かを含める宣言的な方法を組み合わせたものであり、HTML に対して同じことを行うライブラリが世の中にあると思います。実際、C# html シリアライゼーションをグーグルで検索すると、stackoverflow に関するいくつかの有用な投稿にたどり着きます。

于 2013-05-23T16:37:30.117 に答える
0
StringBuilder sb = new StringBuilder();
List<MyWidget> MyWidgets = GetMyWidgets().ToList();
if(MyWidgets.Count!=0)
{
    sb.Append("This is header text");
    MyWidgets.Foreach(w => sb.Append("This is info about widget: " + w.SomeInfo));
    sb.Append("This is footer text");
}
于 2013-05-23T16:28:41.050 に答える
0

これを置き換えることができます:

foreach(MyWidget widget in MyWidgets)
{
    sb.Append("This is info about widget: "+widget.SomeInfo);
}

これとともに:

MyWidgets.ToList().ForEach(x => sb.Append("This is info about widget: "+ x.SomeInfo);
于 2013-05-23T16:28:57.757 に答える