检查 Console.ReadLine 是否为空,而不将其分配给变量。

huangapple go评论166阅读模式
英文:

Checking Console.ReadLine is empty without assigning it to a variable

问题

我想将Console.ReadLine的结果解析为浮点数,并处理它可能为空的情况。

可以在2行内完成。

不过,我想在一行内完成。

有没有办法在不先将其分配给变量的情况下检查Console.ReadLine()。

例如:

var total = float.Parse(Console.ReadLine() == null ? "0" : Console.ReadLine())

我的示例是错误的,因为我简单地重复了Console.ReadLine()。

从我派生出的正确问题格式是:

string? input = Console.ReadLine();
total = float.Parse(input ?? "0");

是否有一种实际在一行内完成的方法?

提前感谢您的建议。

@
*编辑

事实证明,我需要检查是否完全为空和是否为空格,以防万一。
整个代码块变成了:

if (string.IsNullOrEmpty(fieldValue) || string.IsNullOrWhiteSpace(fieldValue))
      fieldValue = "0";
floatAccVal = float.Parse(fieldValue);
英文:

I would like to parse the result of Console.ReadLine to float, and handle the possibility of it being null too.

It could be done in 2 lines.

However, I would like to do it within 1 line.

Is there any way to check a Console.ReadLine() without first assigning it to a variable.

For example:

var total = float.Parse(Console.ReadLine() == null ? "0" : Console.ReadLine())

My example is wrong as I simply repeated the Console.ReadLine().

The correct format to the question I derived from is:

string? input = Console.ReadLine();
total = float.Parse(input ?? "0");

Is there any way to actually do it within one line?

Thanks in advance for suggestions.

@
*Edit

Turns out I need to check for totally empty and whitespaces just in case too.
and the whole chunk becomes:

if (string.IsNullOrEmpty(fieldValue) || string.IsNullOrWhiteSpace(fieldValue))
      fieldValue = "0";
floatAccVal = float.Parse(fieldValue);

答案1

得分: 4

以下是翻译好的部分:

尽管在一行中使用它与代码变得难以阅读的事实相比没有太多好处,但可以通过使用以下代码来实现:

var total = float.TryParse(Console.ReadLine(), out float value) ? value : 0;

UPD:如果您不想为额外的变量分配内存,您可以使用以下代码:

float.TryParse(Console.ReadLine(), out var value);

如果ReadLine()无法解析,value将被设置为默认值,即0(对于float来说)。

英文:

Although there is no much benefits to use it in one line comparing to that fact that code is getting harder to read, it is possible to do it by using next code:

var total = float.TryParse(Console.ReadLine(), out float value) ? value : 0;

UPD: if you don't wont to allocate the memory for additional variables, you can use the next code:

float.TryParse(Console.ReadLine(), out var value);

In case if ReadLine() cannot be parsed, the value will be set to default, that is 0 for float.

答案2

得分: 2

使用模式匹配,可以在一行内完成,以引入变量作为条件的一部分:

```csharp
float f = Console.ReadLine() is string line ? float.Parse(line) : 0f;

这确实引入了一个新变量,但仍在单行内。

你原来的代码 float.Parse(Console.ReadLine() ?? "0") 也可以工作。

如果你想以相同的方式处理字符串,模式匹配也可以轻松处理,尽管在这一点上稍微繁琐,除非我有特殊原因,否则我可能会使用一个 if 语句:

float f = Console.ReadLine() is string line && line != "" ? float.Parse(line) : 0f;

<details>
<summary>英文:</summary>

You can do it in one line, using pattern matching to introduce a variable as part of a condition:

```csharp
float f = Console.ReadLine() is string line ? float.Parse(line) : 0f;

That does introduce a new variable - but it's still within a single line.

Your original code of float.Parse(Console.ReadLine() ?? &quot;0&quot;) would also work.

If you want to handle an empty string in the same way, pattern matching can handle that easily too, although it's slightly more fiddly at this point and I'd probably use an if statement unless I had a particular reason not to:

float f = Console.ReadLine() is string line &amp;&amp; line != &quot;&quot; ? float.Parse(line) : 0f;

答案3

得分: 1

另一种做法是在C#中重新创建类似Kotlin的作用域函数,特别是let。这些函数基本上允许您将几乎任何东西转化为单个表达式。

public static class ScopeFunctions {
    public static R Let<T, R>(this T t, Func<T, R> block) => block(t);

    // 其他可能有用的函数
    public static void Let<T>(this T t, Action<T> block) => block(t);
    public static T Also<T, R>(this T t, Func<T, R> block) {
        block(t);
        return t;
    }
    public static T Also<T>(this T t, Action<T> block) {
        block(t);
        return t;
    }
}

然后,你展示的两行代码可以写成:

var result = Console.ReadLine()?.Let(line => float.Parse(line)) ?? 0;
// 或者这样,我觉得不够可读,但更短
var result = Console.ReadLine()?.Let(float.Parse) ?? 0;

不过,在实际应用中,我会像Ivan Vydrin的答案中所建议的那样使用TryParse,因为它比借用某些Kotlin功能更符合C#的习惯用法,而且还能处理无效的输入。

英文:

Another way you could do this is to recreate something similar to Kotlin's scope functions in C#, specifically let. These basically let you turn almost anything into a single expression.

public static class ScopeFunctions {
    public static R Let&lt;T, R&gt;(this T t, Func&lt;T, R&gt; block) =&gt; block(t);

    // others that might be useful
    public static void Let&lt;T&gt;(this T t, Action&lt;T&gt; block) =&gt; block(t);
    public static T Also&lt;T, R&gt;(this T t, Func&lt;T, R&gt; block) {
        block(t);
        return t;
    }
    public static T Also&lt;T&gt;(this T t, Action&lt;T&gt; block) {
        block(t);
        return t;
    }
}

The two lines you showed can then be written as:

var result = Console.ReadLine()?.Let(line =&gt; float.Parse(line)) ?? 0;
// or this, which I find less readable but is shorter
var result = Console.ReadLine()?.Let(float.Parse) ?? 0;

In practice though, I would go with TryParse like in Ivan Vydrin's answer, as that is a lot more idiomatic C# than borrowing some Kotlin feature, and also handles invalid inputs.

huangapple
  • 本文由 发表于 2023年2月27日 13:11:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/75576951.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定