用于在 C# 中追加集合的 StringBuilder 扩展方法

发布于 2024-07-10 14:47:13 字数 600 浏览 4 评论 0原文

在 C# 中,我试图为 StringBuilder 构建一个名为 AppendCollection() 的扩展方法,它可以让我执行以下操作:

var sb1 = new StringBuilder();
var sb2 = new StringBuilder();
var people = new List<Person>() { ...init people here... };
var orders = new List<Orders>() { ...init orders here... };

sb1.AppendCollection(people, p => p.ToString());
sb2.AppendCollection(orders, o => o.ToString());

string stringPeople = sb1.ToString();
string stringOrders = sb2.ToString();

stringPeople 最终会为列表中的每个人生成一行。 每一行都是 p.ToString() 的结果。 对于 stringOrders 也是如此。 我不太确定如何编写代码以使 lambda 与泛型一起使用。

In C#, I'm trying to build an extension method for StringBuilder called AppendCollection() that would let me do this:

var sb1 = new StringBuilder();
var sb2 = new StringBuilder();
var people = new List<Person>() { ...init people here... };
var orders = new List<Orders>() { ...init orders here... };

sb1.AppendCollection(people, p => p.ToString());
sb2.AppendCollection(orders, o => o.ToString());

string stringPeople = sb1.ToString();
string stringOrders = sb2.ToString();

stringPeople would end up with a line for each person in the list. Each line would be the result of p.ToString(). Likewise for stringOrders. I'm not quite sure how to write the code to make the lambdas work with generics.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

掩耳倾听 2024-07-17 14:47:14

这个方法应该返回什么? 我可以看到一个字符串,但是如果您要附加到 StringBuilder,为什么呢?

你想要做的事情相当简单,但你需要准确地解释你想要什么。

更新:

这是我的看法。 如果您只是要传递一个新的 StringBuilder 并返回一个字符串,那么使用扩展方法是愚蠢且毫无意义的。

更新2:

既然我看到了这种用法,你所做的就是不好的做法。 理想情况下,您应该做的是这样的:

public static string Print<T>(this IEnumerable<T> col, Func<T,string> printer)
{
  var sb = new StringBuilder();
  foreach (T t in col)
  {
    sb.AppendLine(printer(t));
  }
  return sb.ToString();
}

string[] col = { "Foo" , "Bar" };
string lines = col.Print( s => s);

更新 3:

经过更多澄清:(

public static void AppendCollection<T>(this StringBuilder sb, 
   List<T> col, Func<T,string> printer)
{
  col.ForEach( o => sb.AppendLine(printer(o)));
}

与 bruno conde 所说的相同)

现在您真的不再需要它了:)

What is this method suppose to return? I can see a string, but why, if you are appending to a StringBuilder?

What you are trying to do is rather easy, but you need to explain exactly what you want.

Update:

Here's my take. Using an extension method for this is stupid and pointless if you are just going to pass in a new StringBuilder and return a string.

Update 2:

Now that I see that usage, what you are doing is bad practice. What you should ideally be doing is something like:

public static string Print<T>(this IEnumerable<T> col, Func<T,string> printer)
{
  var sb = new StringBuilder();
  foreach (T t in col)
  {
    sb.AppendLine(printer(t));
  }
  return sb.ToString();
}

string[] col = { "Foo" , "Bar" };
string lines = col.Print( s => s);

Update 3:

After more clarification:

public static void AppendCollection<T>(this StringBuilder sb, 
   List<T> col, Func<T,string> printer)
{
  col.ForEach( o => sb.AppendLine(printer(o)));
}

(which is the same as bruno conde said)

And now you dont really need it anymore :)

优雅的叶子 2024-07-17 14:47:13

使用 Func 委托。

public static void AppendCollection<T>(this StringBuilder sb, 
                                       IEnumerable<T> collection, Func<T, string> method) {
   foreach(T x in collection) 
       sb.AppendLine(method(x));
}

Use the Func<T,string> delegate.

public static void AppendCollection<T>(this StringBuilder sb, 
                                       IEnumerable<T> collection, Func<T, string> method) {
   foreach(T x in collection) 
       sb.AppendLine(method(x));
}
残花月 2024-07-17 14:47:13
 public static void AppendCollection<T>(this StringBuilder builder, IEnumerable<T> list, Func<T,string> func)
        {
            foreach (var item in list)
            {
                builder.AppendLine(func(item));
            }
        }

我不会返回字符串,我只是将其附加到传入的原始 Stringbuilder 中。

 public static void AppendCollection<T>(this StringBuilder builder, IEnumerable<T> list, Func<T,string> func)
        {
            foreach (var item in list)
            {
                builder.AppendLine(func(item));
            }
        }

I wouldn't return a string, I would just append it to the original Stringbuilder that was passed in.

一直在等你来 2024-07-17 14:47:13

我不确定您是否需要那么努力:

 public static void AppendCollection( this StringBuilder builder,
                                      ICollection collection )
 {
     foreach (var item in collection)
     {
        builder.AppendLine( Convert.ToString( item ) );
     }
 }

用作

 List<Person> people = ...

 StringBuilder builder = new StringBuilder();
 builder.AppendCollection( people );
 var s = builder.ToString();

当然,Person 需要重写 ToString() 才能为 Person 对象生成正确的输出。

I'm not sure you need to work that hard:

 public static void AppendCollection( this StringBuilder builder,
                                      ICollection collection )
 {
     foreach (var item in collection)
     {
        builder.AppendLine( Convert.ToString( item ) );
     }
 }

Used as

 List<Person> people = ...

 StringBuilder builder = new StringBuilder();
 builder.AppendCollection( people );
 var s = builder.ToString();

Of course, Person needs to override ToString() to produce the correct output for a Person object.

此刻的回忆 2024-07-17 14:47:13

类似于:

  public static void AppendCollection<TItem>(this StringBuilder builder, IEnumerable<TItem> items, Func<TItem, string> valueSelector)
  {
       foreach(TItem item in items)
       {  
            builder.Append(valueSelector(item));
       }
  }

我会添加一个有用的默认值,以节省在 90% 的情况下指定 lambda...

   public static void AppendCollection<TItem>(this StringBuilder builder, IEnumerable<TItem> items)
  {
      AppendCollection(builder, items, x=>x.ToString());
   }

Something like:

  public static void AppendCollection<TItem>(this StringBuilder builder, IEnumerable<TItem> items, Func<TItem, string> valueSelector)
  {
       foreach(TItem item in items)
       {  
            builder.Append(valueSelector(item));
       }
  }

I would add in a useful default to save specifiying the lambda in 90% of cases...

   public static void AppendCollection<TItem>(this StringBuilder builder, IEnumerable<TItem> items)
  {
      AppendCollection(builder, items, x=>x.ToString());
   }
☆獨立☆ 2024-07-17 14:47:13

我的版本:

    public static string AppendCollection<T>(this StringBuilder sb, IEnumerable<T> enumerable, Func<T, string> method)
    {
        List<T> l = new List<T>(enumerable);
        l.ForEach(item => sb.AppendLine(method(item)));
        return sb.ToString();
    }

但在这种情况下你不应该返回字符串。 我希望

    public static void AppendCollection<T>(this StringBuilder sb, IEnumerable<T> enumerable, Func<T, string> method)
    {
        List<T> l = new List<T>(enumerable);
        l.ForEach(item => sb.AppendLine(method(item)));
    }

使用以下内容:

        sb.AppendCollection(people, p => p.ToString());
        sb.AppendCollection(orders, o => o.ToString());
        Console.WriteLine(sb.ToString());

My version:

    public static string AppendCollection<T>(this StringBuilder sb, IEnumerable<T> enumerable, Func<T, string> method)
    {
        List<T> l = new List<T>(enumerable);
        l.ForEach(item => sb.AppendLine(method(item)));
        return sb.ToString();
    }

but you shouldn't return a string in this case. I would prefer the following:

    public static void AppendCollection<T>(this StringBuilder sb, IEnumerable<T> enumerable, Func<T, string> method)
    {
        List<T> l = new List<T>(enumerable);
        l.ForEach(item => sb.AppendLine(method(item)));
    }

to be used like:

        sb.AppendCollection(people, p => p.ToString());
        sb.AppendCollection(orders, o => o.ToString());
        Console.WriteLine(sb.ToString());
被翻牌 2024-07-17 14:47:13
static class SBExtention
{
  static string AppendCollection<T>(this StringBuilder sb, 
                                    IEnumerable<T> coll, 
                                    Func<T,string> action)
  {
       foreach(T t in coll)
       {
          sb.Append(action(t));
          sb.Append("\n");
       }
       return sb.ToString();

  }
}

但是,我认为让它返回 StringBuilder 会更好。 这样你就可以链接它:

  static StringBuilder AppendCollection<T>(this StringBuilder sb, 
                                    IEnumerable<T> coll, 
                                    Func<T,string> action)
  {
       // same
       return sb;

  }

string peopleAndOrders =
sb.AppendCollection(people, p => p.ToString())
.AppendCollection(orders, o => o.ToString()).ToString();

我同意 Jennifer 关于默认情况的看法:

   public static StringBuilder AppendCollection<TItem>(
                  this StringBuilder builder, 
                  IEnumerable<TItem> items)
  {
      return AppendCollection(builder, items, x=>x.ToString());
   }

string peopleAndOrders =
sb.AppendCollection(people).AppendCollection(orders).ToString();

static class SBExtention
{
  static string AppendCollection<T>(this StringBuilder sb, 
                                    IEnumerable<T> coll, 
                                    Func<T,string> action)
  {
       foreach(T t in coll)
       {
          sb.Append(action(t));
          sb.Append("\n");
       }
       return sb.ToString();

  }
}

However, I think you'll be better off having it return the StringBuilder. That way you could chain it:

  static StringBuilder AppendCollection<T>(this StringBuilder sb, 
                                    IEnumerable<T> coll, 
                                    Func<T,string> action)
  {
       // same
       return sb;

  }

string peopleAndOrders =
sb.AppendCollection(people, p => p.ToString())
.AppendCollection(orders, o => o.ToString()).ToString();

And I agree with Jennifer about the default case:

   public static StringBuilder AppendCollection<TItem>(
                  this StringBuilder builder, 
                  IEnumerable<TItem> items)
  {
      return AppendCollection(builder, items, x=>x.ToString());
   }

string peopleAndOrders =
sb.AppendCollection(people).AppendCollection(orders).ToString();

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文