Как написать это лучше? - PullRequest
       6

Как написать это лучше?

3 голосов
/ 06 апреля 2010

Давайте посмотрим на этот код:

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;

Это лучший способ написать это в меньшем количестве кода и лучше (должно быть :-))? Может быть, используя лямбду (но дайте мне знать, как)?

Заранее спасибо!

Ответы [ 7 ]

9 голосов
/ 06 апреля 2010

Только к вашему сведению, вы никогда не добавляете новый HouseAnnouncement в свой список, и ваш цикл никогда не будет выполняться для строки last , но я предполагаю, что это ошибки в примере, а нев вашем реальном коде.

Вы можете сделать что-то вроде этого:

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

Я обычно стремлюсь к читабельности, а не к краткости, но мне кажется, что это довольно читабельно.

Обратите внимание, что, хотя вы все еще можете кэшировать DataTable и использовать table.powierzchniaColumn в лямбда-выражении, я исключил это, чтобы вы не использовали замыкание, которое не было действительно необходимым (замыкания создают существенную сложностьвнутренняя реализация лямбды, поэтому я избегаю их, если это возможно).

Если для вас важно сохранить ссылки на столбцы, как они, то вы можете сделать это следующим образом:

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, который генерирует компилятор, но он должен помочь вам.

5 голосов
/ 06 апреля 2010

Вы можете сделать что-то подобное в 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 голосов
/ 06 апреля 2010

Ваше "если заявление" не нужно. Ваш "for loop" уже позаботится об этом случае.

Кроме того, ваш цикл for не будет выполняться, когда количество строк в таблице равно 1. Это кажется ошибкой, а не преднамеренно, но я могу ошибаться. Если вы хотите это исправить, просто удалите «-1»:

for (int i = 0; i < table.Rows.Count; i++)
1 голос
/ 07 апреля 2010

Не может быть намного проще, чем один цикл for и никаких операторов 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-версия, но анализируется быстрее мозгом программиста. :)

1 голос
/ 06 апреля 2010

Ну, во-первых, у вас, похоже, есть ошибка "один за другим":

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

Если в вашей таблице три строки, она будет работать, пока i меньше 3 - 1 или 2, что означает, что она будет работать для строк 0 и 1, но не для строки 2. Возможно, это не то, что вы намереваюсь.

0 голосов
/ 06 апреля 2010

Я мог бы сделать что-то вроде этого:

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();
0 голосов
/ 06 апреля 2010

Для меня предпочтительнее удобочитаемость, нежели краткость кода, если производительность не является жертвой.Кроме того, я уверен, что любой, кто позже должен будет поддерживать код, также оценит это.Даже когда я поддерживаю свой собственный код, я не хочу смотреть на него, скажем пару месяцев спустя, и думать: «какого черта я пытался достичь»

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...