【问题标题】:How can i assign a value to a char variable in a foreach loop? C#如何在 foreach 循环中为 char 变量赋值? 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 == ',' 也出现在 ifelse if 中,这没有多大意义。
  • 可能duplicate.
  • 语言规范明确声明 “变量 v 在嵌入语句中是只读的。” 但没有说明原因。 docs.microsoft.com/en-us/dotnet/csharp/language-reference/…
  • 替代方法if ("0123456789.".Contains(ch))if (char.IsDigit(ch) || ch == '.')

标签: c# loops foreach char stringbuilder


【解决方案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);
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-12-09
        相关资源
        最近更新 更多