C# 表达式和循环之美

发布于 2024-12-18 03:35:21 字数 375 浏览 0 评论 0原文

这可能相当主观,但是当控制变量在循环中更新时,人们通常如何在 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# 的表达式似乎不能那样工作:(

This is probably pretty subjective, but how do people generally lay out their loop control in C# when the control variable is updated in the loop? The pedant in me doesn't like the separate declaration and repetition involved. eg.

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

    line = reader.ReadLine();
}

The C coder in me wants to change this to

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

but C#'s expressions don't seem to work that way :(

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

夏日落 2024-12-25 03:35:22

选项:

1) 将变量声明为循环,但在条件中对其进行赋值:

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

2) 使用 for 循环:

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

3) 创建一个扩展方法,将读取器转换为 IEnumerable,然后使用:

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

就我个人而言,我喜欢尽可能使用最后一种形式 - 否则我会使用第一种形式。

Options:

1) Declare the variable the loop, but assign it in the condition:

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

2) Use a for loop instead:

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

3) Create an extension method to turn a reader into an IEnumerable<String> and then use:

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

Personally I like the last one where possible - otherwise I'd use the first form.

小糖芽 2024-12-25 03:35:22

您不能在表达式内声明变量。

您可以写

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

为了更清楚,我更喜欢写

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

然而,最好的选择是

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

}

这将执行等效的操作。
如果您正在读取其他流,则可以创建一个扩展方法,该方法使用以前的语法来启用 foreach 循环。

You can't declare a variable inside an expression.

You can write

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

To make it clearer, I prefer to write

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

However, the best alternative is

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

}

This will perform equivalently.
If you're reading some other stream, you can create an extension method that uses the previous syntax to enable foreach loops.

入画浅相思 2024-12-25 03:35:22

就我个人而言,我更喜欢:

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

尽管总是有 for 结构作为替代:

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

Personally, I prefer:

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

There's always the for construct as an alternative though:

for (string line = reader.ReadLine(); line != null; line = reader.ReadLine())
{
  ...
}
非要怀念 2024-12-25 03:35:22

我通常会写这样的内容:

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

I usually write something like:

string line;
while((line = reader.ReadLine()) != null)
{
}
2024-12-25 03:35:22

我同意重复 reader.ReadLine() 表达式不好。一种方法是使用 while(true)break

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

  //do something with line
}

I agree that repeating the reader.ReadLine() expression isn't good. One way is to use while(true) and break:

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

  //do something with line
}
攒一口袋星星 2024-12-25 03:35:22

怎么样:

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);
}

How about:

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;
    }
}

and then use it something like this:

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

or would you prefer:

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

that could be defined as:

public static IEnumerable<R> NotNull<T, R>(this T self, Func<T, R> yielder)
{
    return self.ToSequence(yielder, (r) => r != null);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文