C # выражения и цикл красоты - PullRequest
2 голосов
/ 24 ноября 2011

Это, вероятно, довольно субъективно, но как люди обычно выкладывают свой элемент управления цикла в C #, когда переменная управления обновляется в цикле? Педанту во мне не нравится отдельное объявление и повторение. например.

string line = reader.ReadLine();
while (line != null)
{
    //do something with line

    line = reader.ReadLine();
}

Кодер C во мне хочет изменить это на

while (string line = reader.ReadLine() != null)
{
    //do something with line
}

но выражения C #, похоже, не работают таким образом: (

Ответы [ 6 ]

7 голосов
/ 24 ноября 2011

Параметры:

1) Объявите переменную цикла, но присвойте ее в условии:

string line;
while ((line = reader.ReadLine()) != null)
{
}

2) Вместо этого используйте цикл for:

for (string line = reader.ReadLine(); line != null; line = reader.ReadLine())
{
}

3) Создайте метод расширения, чтобы превратить читателя в IEnumerable<String>, а затем используйте:

foreach (string line in reader.ReadLines())
{
}

Лично мне нравится последний, где это возможно, иначе я бы использовал первую форму.

4 голосов
/ 24 ноября 2011

Вы не можете объявить переменную внутри выражения.

Вы можете написать

string line;
while (line = reader.ReadLine() != null)

Чтобы было понятнее, я предпочитаю писать

string line;
while (null != (line = reader.ReadLine()))

Однако, лучшая альтернатива -

foreach(string line in File.ReadLines(path) {

}

Это будет работать аналогично.
Если вы читаете какой-то другой поток, вы можете создать метод расширения, который использует предыдущий синтаксис для включения циклов foreach.

2 голосов
/ 24 ноября 2011

Лично я предпочитаю:

string line;
while (line = reader.ReadLine() != null)
{
  ...
}

В качестве альтернативы всегда есть конструкция for:

for (string line = reader.ReadLine(); line != null; line = reader.ReadLine())
{
  ...
}
1 голос
/ 24 ноября 2011

Я обычно пишу что-то вроде:

string line;
while((line = reader.ReadLine()) != null)
{
}
0 голосов
/ 24 ноября 2011

Как насчет:

public static IEnumerable<R> ToSequence<T, R>(this T self, 
    Func<T, R> yielder, Func<R, bool> condition)
{
    R result = yielder(self, R);
    while (condition(result))
    {
        yield return result;
    }
}

, а затем используйте его примерно так:

foreach (var line in reader.ToSequence(
    (r) => r.ReadLine(), 
    (line) => line != null))
{
    // do some stuff to line
}

или вы бы предпочли:

foreach (var line in reader.NotNull(r => r.ReadLine()))
{
    // do some stuff to line...
}

, который может быть определен как:

public static IEnumerable<R> NotNull<T, R>(this T self, Func<T, R> yielder)
{
    return self.ToSequence(yielder, (r) => r != null);
}
0 голосов
/ 24 ноября 2011

Я согласен, что повторять выражение reader.ReadLine() нехорошо.Одним из способов является использование while(true) и break:

while(true)
{
  string line = reader.ReadLine();
  if(line == null)
    break;

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