是否允许多个条件使用 switch-case 语句?

Are switch-case statements allowed for multiple conditions?

我打算做一个复数 class,但我的一个函数似乎有太多涉及多个语句的条件。这是带有 ToString() 函数的程序片段:

public override string ToString()
{
    if (this.real == 0 && this.imaginary == 0)
    {
        return "0";
    }
    else if (this.real == 0 && this.imaginary == 1)
    {
        return "i";
    }
    else if (this.real == 0 && this.imaginary == -1)
    {
        return "-i";
    }
    else if (this.real == 0 && (this.imaginary != 1 && this.imaginary != -1))
    {
        return String.Concat(this.imaginary.ToString(), "i");
    }
    else if (this.real != 0 && this.imaginary == 0)
    {
        return String.Concat(this.real.ToString());
    }
    else if (this.real != 0 && this.imaginary == 1)
    {
        return String.Concat(this.real.ToString(), " + i");
    }
    else if (this.real != 0 && this.imaginary == -1)
    {
        return String.Concat(this.real.ToString(), " - i");
    }
    else if (this.real != 0 && this.imaginary < -1)
    {
        this.imaginary = -this.imaginary;
        return String.Concat(this.real.ToString(), " - ", this.imaginary.ToString(), "i");
    }
    return String.Concat(this.real.ToString(), " + ", this.imaginary.ToString(), "i");
}

switch 语句对多个条件有用吗?

通过消除冗余检查使代码更具可读性。

使用字符串插值代替 String.Concat

public override string ToString()
{
     if (real == 0)
     {
          if (imaginary == 0)
          {
              return "0";
          }

          if (imaginary == 1)
          {
              return "i";
          }

          if (imaginary == -1)
          {
              return "-i";
          }

          if (imaginary != 1)
          {
              return $"{imaginary}i";
          }
    }
    else
    {
         if (imaginary == 0)
         {
             return real.ToString();
         }
         if (imaginary == 1)
         {
             return $"{real} + i";
         }
         if (imaginary == -1)
         {
             return $"{real} - i";
         }
         if (imaginary < -1)
         {
              imaginary = -imaginary;
              return $"{real} - {imaginary}i"; 
         }
  }

  return $"{real} + {imaginary}i";
}

您的代码过于复杂和冗余,因为您为每种可能的情况提出了一个单独的分支。如果您将代码分解并执行以下操作,您的代码将会简单得多:

  1. 获取实部(如果有的话)和虚部(如果有的话)
  2. 如果有两部分就合并起来

以下将执行此操作:

private string RealPartString()
{
    if (real == 0) { return imaginary == 0 ? "0" : null; }

    return real.ToString();
}

private string ImaginaryPartString()
{
    if (imaginary == 0) { return null; }

    var abs = Math.Abs(imaginary);
    var number = abs == 1 ? "" : abs.ToString();
    // Only include the sign here if there is no real part
    var sign = real == 0 && imaginary < 0 ? "-" : "";

    return sign + number + "i";
}

public override string ToString()
{
    var parts = new[] { RealPartString(), ImaginaryPartString() }.Where(s => s != null);
    var sign = imaginary < 0 ? " - " : " + ";

    return string.Join(sign, parts);
}

switch 中你不能有一个以上的条件,但看起来 this.real 只有两种可能性,0 或 1,所以你可以去掉它并为 [= 使用一个开关13=].

此外,使用 String.Format() 或字符串插值代替 String.Concat() 可能更好。

public override string ToString() {
    if (this.real == 0) {
        switch(this.imaginary) {
            case 0:
                return "0";
            case 1:
                return "i";
            case -1:
                return "-i";
            default:
                return $"{this.imaginary}i";
    }
    else {
        switch(this.imaginary) {
            case 0:
                return this.real.ToString();
            case 1:
                return $"{this.real} + i";
            case -1:
                return $"{this.real} - i";
            default:
                if (this.imaginary < -1) {
                    this.imaginary = -this.imaginary;
                    return $"{this.real} - {this.imaginary}i";
                }
        }
    }
    return $"{this.real} + {this.imaginary}i";
}