寻找有关从此代码段删除重复内容的建议:
foreach (Car car in carList) {
DataRow row = NewRow();
StringBuilder sbConfigurations = new StringBuilder();
foreach (ConfigurationItem configurationItem in car.Configurations)
sbConfigurations.AppendFormat("{0}: {1}\n", configurationItem.Name, configurationItem.Value);
row["configurations"] = sbConfigurations;
StringBuilder sbOptionals = new StringBuilder();
foreach (OptionalItem optionalItem in car.Optionals)
sbOptionals.AppendFormat("{0}, ", optionalItem.Name);
row["optionals"] = sbOptionals;
Rows.Add(row);
}
编辑:这是一个简化的上下文,可能会有更多像这样的列表连接
答案 0 :(得分:3)
我真的不认为删除你所说的“重复”是必要的。您不会出现两次相同的代码,但会出现两次相似的代码。这很常见,无需担心。
答案 1 :(得分:2)
我同意没有太多的重复,但也许这个“字面翻译”进入Linq Extensions 是你正在寻找的(键入浏览器,所以没有测试 - ):
foreach (Car car in carList) {
DataRow row = NewRow();
row["configurations"] = car.Configurations.Aggregate(new StringBuilder(), (a,i) => a.AppendFormat("{0}: {1}\n", i.Name, i.Value));
row["optionals"] = car.Optionals.Aggregate(new StringBuilder(), (a,i) => a.AppendFormat("{0}, ", i.Name));
Rows.Add(row);
}
或者,如果没有使用stringbuilders,你可以写得更清晰(/高效?):
提取lambda会缩短行数:
Func<Car, string> nameValue = car => string.Format("{0}: {1}\n", car.Name, car.Value);
foreach (var car in carList) {
var row = new Dictionary<string, string>();
row["configurations"] = string.Join("\n", car.Configurations.Select(nameValue));
row["optionals"] = string.Join(", ", car.Optionals.Select(i => i.Name));
list.Add(row);
}
注意在C#4.0之前,您需要对.ToArray()
的第二个参数进行额外的string.Join
次调用
答案 2 :(得分:2)
如何将问题颠倒过来。不是让函数理解每个对象的DataRow
格式,而是让每个对象都理解DataRow
格式。如果您没有使用object.ToString()
进行任何操作,可以ConfigurationItem
和OptionalItem
实施object.ToString()
:
class ConfigurationItem
{
public string override ToString()
{
return string.Format("{0}: {1}\n", Name, Value);
}
}
class OptionalItem
{
public string override ToString()
{
return string.Format("{0}, ", Name);
}
}
现在,您可以对所有类型的对象使用单个循环:
string BuildDataRowString(IEnumerable collection)
{
var sb = new StringBuilder();
foreach (var o in collection) sb.Append(o.ToString());
return sb.ToString();
}
row["configurations"] = car.Configurations.BuildDataRowString();
row["optionals"] = car.Optionals.BuildDataRowString();
如果您出于其他目的需要object.ToString()
,可以为“DataRow
格式”添加自定义格式:
class ConfigurationItem : IFormattable
{
public string override ToString(string format, IFormatProvider formatProvider)
{
if (format == "D") {
return string.Format(formatProvider, "{0}: {1}\n", Name, Value);
}
return this.ToString(); // otherwise format as default
}
}
class OptionalItem : IFormattable
{
public string override ToString(string format, IFormatProvider formatProvider)
{
if (format == "D") {
return string.Format(formatProvider, "{0}, ", Name);
}
return this.ToString(); // otherwise format as default
}
}
string BuildDataRowString(this IEnumerable e, string format)
{
StringBuilder sb = new StringBuilder();
foreach (var o in e) sb.AppendFormat("{0:D}", o);
return sb.ToString();
}