在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。我不太清楚如何编写代码来使lambdas与泛型一起使用。
答案 0 :(得分:10)
使用Func<T,string>
代表。
public static void AppendCollection<T>(this StringBuilder sb,
IEnumerable<T> collection, Func<T, string> method) {
foreach(T x in collection)
sb.AppendLine(method(x));
}
答案 1 :(得分:5)
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中。
答案 2 :(得分:3)
我不确定你是否需要努力工作:
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对象生成正确的输出。
答案 3 :(得分:3)
类似的东西:
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());
}
答案 4 :(得分:3)
我的版本:
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());
答案 5 :(得分:2)
这种方法假设要返回什么?我可以看到一个字符串,但是为什么,如果你要附加到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说的相同)
现在你真的不再需要了它:)
答案 6 :(得分:2)
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 =&gt; p.ToString()) .AppendCollection(orders,o =&gt; 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(人).AppendCollection(订单)的ToString();