如何以更好的方式写这个?

时间:2010-04-06 18:39:37

标签: c# design-patterns lambda

我们来看看这段代码:

IList<IHouseAnnouncement> list = new List<IHouseAnnouncement>();
var table = adapter.GetData(); //get data from repository object -> DataTable

if (table.Rows.Count >= 1)
{
    for (int i = 0; i < table.Rows.Count; i++)
    {
        var anno = new HouseAnnouncement();
        anno.Area = float.Parse(table.Rows[i][table.areaColumn].ToString());
        anno.City = table.Rows[i][table.cityColumn].ToString();
        list.Add(anno);
    }
  }
  return list;

用更少的代码和更好的方式(必须是:-)来写这个更好的方法吗?也许使用lambda(但让我知道如何)?

提前致谢!

7 个答案:

答案 0 :(得分:9)

仅供参考,您永远不会将新的HouseAnnouncement添加到您的列表中,并且您的循环将永远不会执行 last 行,但我假设这些是错误的例子而不是实际的代码。

你可以这样做:

return adapter.GetData().Rows.Cast<DataRow>().Select(row =>
    new HouseAnnouncement()
    {
        Area = Convert.ToSingle(row["powierzchnia"]),
        City = (string)row["miasto"],
    }).ToList();

我通常为了简洁而可读性,但我觉得这很可读。

请注意,虽然您仍然可以在lambda中缓存DataTable并使用table.powierzchniaColumn,但我删除了它,因此您没有使用非必要的闭包(闭包会带来实质性的复杂性)对于lambda的内部实现,如果可能的话我会避免它们。)

如果保持列引用不重要,那么你可以这样做:

using (var table = adapter.GetData())
{
    return table.Rows.Cast<DataRow>().Select(row =>
        new HouseAnnouncement()
        {
            Area = Convert.ToSingle(row[table.powierzchniaColumn]),
            City = (string)row[table.miastoColumn],
        }).ToList();
}

这会增加编译器生成的实际IL的复杂性,但应该为你做好准备。

答案 1 :(得分:5)

你可以在Linq做这样的事情:

var table = adapter.GetData();
var q = from row in table.Rows.Cast<DataRow>()
        select new HouseAnnouncement() 
           { Area = float.Parse(row[table.areaColumn].ToString()),
             City = row[table.cityColumn].ToString()
           };
return q.ToList();

答案 2 :(得分:2)

您的“if声明”不是必需的。你的“for循环”已经处理了这种情况。

此外,当你的表行数为1时,你的“for循环”将不会执行。这似乎是一个错误,而不是设计,但我可能是错的。如果你想解决这个问题,只需取出“-1”:

for (int i = 0; i < table.Rows.Count; i++)

答案 3 :(得分:1)

嗯,首先,你似乎有一个错误的错误:

for (int i = 0; i < table.Rows.Count - 1; i++)
{
}

如果你的表有三行,这将在i小于3 - 1或2时运行,这意味着它将运行第0行和第1行而不是第2行。这可能不是你打算做什么。

答案 4 :(得分:1)

不能简单地说一个for-loop而不是if语句:

var table = adapter.GetData(); //get data from repository object -> DataTable
IList<IHouseAnnouncement> list = new List<IHouseAnnouncement>(table.Rows.Count);

for (int i = 0; i < list.Length; i++)
{
   list[i] = new HouseAnnouncement();
   list[i].Area = float.Parse(table.Rows[i][table.areaColumn].ToString());
   list[i].City = table.Rows[i][table.cityColumn].ToString();
}

return list;

它需要比linq-version更多的字符,但程序员的大脑会更快地解析它。 :)

答案 5 :(得分:0)

对我而言,可读性优于对您的代码进行简洁 - 只要性能不是受害者。此外,我确信任何后来必须维护代码的人也会对此表示赞赏 即使在我维护自己的代码时,我也不想看它,比如说几个月之后,并且想“我到底想要完成什么”

答案 6 :(得分:0)

我可能会这样做:

var table = adapter.GetData(); //get data from repository object -> DataTable

return table.Rows.Take(table.Rows.Count-1).Select(row => new HouseAnnouncement() {
    Area = float.Parse(row[table.powierzchniaColumn].ToString()),
    City = row[table.miastoColumn].ToString()
}).ToList();