如何在 foreach 循环中为 char 变量赋值? C#
Posted
技术标签:
【中文标题】如何在 foreach 循环中为 char 变量赋值? C#【英文标题】:How can i assign a value to a char variable in a foreach loop? C# 【发布时间】:2021-05-02 09:03:03 【问题描述】:我想做的是这样的:
StringBuilder sb = new StringBuilder();
foreach(char ch in valor)
if (ch == ',')
ch = '.';
else if (ch == '0' || ch == '1' || ch == '2' || ch == '3' || ch == '4' || ch == '5' || ch == '6' || ch == '7' || ch == '8' || ch == '9' || ch == ',')
sb.Append(ch);
我想要的是,如果字符是逗号,则将其设为点。但我收到以下错误
不能给'ch'赋值,因为它是一个foreach交互变量
【问题讨论】:
最终目标是什么?ch == ','
也出现在 if
和 else if
中,这没有多大意义。
可能duplicate.
语言规范明确声明 “变量 v 在嵌入语句中是只读的。” 但没有说明原因。 docs.microsoft.com/en-us/dotnet/csharp/language-reference/…
替代方法if ("0123456789.".Contains(ch))
或if (char.IsDigit(ch) || ch == '.')
【参考方案1】:
为什么不在两个 if 分支中追加?
foreach(char ch in valor)
if (ch == ',')
sb.Append('.');
else if (ch == '0' || ch == '1' || ch == '2' || ch == '3' || ch == '4' || ch == '5' || ch == '6' || ch == '7' || ch == '8' || ch == '9')
sb.Append(ch);
【讨论】:
或者在foreach之前使用string.Replace( ",", ".")
?
天哪,不知道我怎么没想到...谢谢!
@Fildor 是的,我就是这样做的,但问题有点不同。可能有 1 亿种方法可以做到这一点。
当然。这只是我想到的第一件事......另外,对我来说这个问题有点像“我怎么能做 x,而我不允许做 x”......所以无论如何,很难回答。【参考方案2】:
简答:不可能。
使用不可变的foreach
索引项,您需要使用这样的中间变量:
foreach ( char ch in valor )
char c = ch;
if ( c == ',' )
c = '.';
if ( c == '0' || c == '1' || c == '2' || c == '3' || c == '4'
|| c == '5' || c == '6' || c == '7' || c == '8' || c == '9'
|| c == '.' )
sb.Append(c);
我删除了else
,因为这似乎是一个错误...
但在这种情况下,您可能更喜欢直接使用for
来避免这个无用的中间变量,从而优化速度和内存:
for (int index = 0; index < valor.Length; index++)
char c = valor[index];
if ( c == ',' )
c = '.';
if ( c == '0' || c == '1' || c == '2' || c == '3' || c == '4'
|| c == '5' || c == '6' || c == '7' || c == '8' || c == '9'
|| c == '.' )
sb.Append(c);
接下来,对于提供的代码,我们可以像这样重构,现在以正确的方式使用else
:
for (int index = 0; index < valor.Length; index++)
char c = valor[index];
if ( c == ',' )
sb.Append('.');
else
if ( c == '0' || c == '1' || c == '2' || c == '3' || c == '4'
|| c == '5' || c == '6' || c == '7' || c == '8' || c == '9' )
sb.Append(c);
另外,对于提供的代码,我们可以改进:
for ( int index = 0; index < valor.Length; index++ )
char c = valor[index];
if ( c == ',' )
sb.Append('.');
else
if ( char.IsDigit(c) ) // or IsNumber
sb.Append(c);
为了更好地优化:
for ( int index = 0; index < valor.Length; index++ )
char c = valor[index];
if ( c == ',' )
sb.Append('.');
else
if ( c >= '0' && c <= '9' )
sb.Append(c);
因此,我们可以使用foreach
编写代码,但优化程度较低,但更简洁:
foreach (char ch in valor )
if ( ch == ',' )
sb.Append('.');
else
if ( ch >= '0' && ch <= '9' )
sb.Append(ch);
Char.IsDigit Method
Char.IsNumber Method
foreach, in (C# reference)
for (C# reference)
【讨论】:
【参考方案3】:只引入一个局部变量
StringBuilder sb = new StringBuilder();
foreach(char ch in valor)
var tmp = ch == ',' ? '.' : ch;
if (char.IsDigit(tmp) || tmp == '.')
sb.Append(tmp);
您也可以使用静态char.IsDigit()
方法来检查字符是否为数字
你也可以只使用 linq:
var sb = new StringBuilder();
sb = valor
.Select(c => c == ',' ? '.' : c)
.Where(c => char.IsDigit(c) || c == '.')
.Aggregate(sb, (sb, c) => sb.Append(c));
【讨论】:
【参考方案4】:你可以试试这个:
StringBuilder sb = new StringBuilder();
var valor = "google,com1234";
if (valor.Contains(','))
valor = valor.Replace(",", ".");
foreach (char ch in valor)
if (ch == '0' || ch == '1' || ch == '2' || ch == '3' || ch == '4' || ch == '5' || ch == '6' || ch == '7' || ch == '8' || ch == '9' || ch == '.')
sb.Append(ch);
【讨论】:
以上是关于如何在 foreach 循环中为 char 变量赋值? C#的主要内容,如果未能解决你的问题,请参考以下文章
如何在mybatis的mapper接口中为更新查询编写foreach循环