【问题标题】:Is it OK to use assignments in expressions?在表达式中使用赋值可以吗?
【发布时间】:2010-09-21 04:04:42
【问题描述】:

我遇到了这段代码,并希望其他人提供他们的观点......这是好是坏? ;)

Class ReportClass
{
 public string ReportName {get; set;}
}

然后在代码中使用如下:

displayReport(ReportClass.ReportName = cmbReportName.SelectedValue.ToString())

这是我能给你的最简单的例子。 问题是......为什么我找不到例子?这会叫什么?这是自找麻烦吗?

编辑:我指的是就地分配。直到今天我才意识到这一点

【问题讨论】:

  • 我指的是就地分配。直到今天我才知道。
  • 这叫什么?就地分配或复合语句?

标签: c# expression variable-assignment


【解决方案1】:

对我来说似乎很好。它可能是用 C# 3.0 编译的,并且允许 C# automatic properties

【讨论】:

  • 自动属性是 C# 3.0 的一部分,而不是 .NET 3.0 - 它们在面向 .NET 2.0 时可以正常工作。
【解决方案2】:

就属性的命名而言,您有一个 ReportClass,我会将其更改为 Report,并且其上的属性从 ReportName 更改为只是 Name。节省您的打字时间(尽管可以使用智能感知)。编码为 Report.Name 时看起来更好。

我知道这有点离题,但是嘿嘿

【讨论】:

    【解决方案3】:

    Microsoft 框架设计指南不鼓励在一行中放置多个语句,除非有直接的语言支持,例如 for 语句。由于对多重赋值有明确的语言支持,

    int a, b, c;
    a = b = c = 0;
    

    是允许的。另一方面,不鼓励使用您的示例中使用的表单代码。

    各位,这个怎么样?

    while ((packetPos = Packet.FindStart(buffer, nextUnconsideredPos)) > -1)
    

    为避免内联赋值,您必须进行冗余分解,如下所示:

    packetPosition = Packet.FindStart(buffer, nextUnconsideredPosition);
    while (packetPosition > -1)
    {
      ...
      packetPosition = Packet.FindStart(buffer, nextUnconsideredPosition);
    }
    

    【讨论】:

    • 这种 while 循环非常惯用,IMO - 这是一个特例,真的。
    【解决方案4】:

    我个人觉得作为参数的赋值不是很可读。由于在参数列表中实际发生了操作,因此整个执行流程发生了偏差。

    我喜欢认为我的代码应该表达意图,而不是保存空格。我在这个例子中的意图正是 EvilSyn 所建议的,首先分配值,然后将其传递给方法。

    【讨论】:

    • 由空格传播的过于简单的代码会让人昏昏欲睡。简洁是所有表达形式的美德。真正的会计师可以用任何语言编写 COBOL。
    【解决方案5】:

    您是指自动属性还是就地分配?

    取决于您的团队 IMO。如果您的团队由 C 风格的开发人员组成。那我觉得还可以。

    但是,如果要由 VB 开发人员进一步维护此代码,那么您需要 使其更具可读性。

    例子? C 语言中的赋值运算符 (=) 也返回它所分配的值。

    var a = 0;
    var b = 0;
    
    // This makes a *and* b equals to 1
    a = b = 1; 
    
    // This line prints 3 and a is now equals to 3
    Console.WriteLine(a = 3);
    
    // This line prints 7 and a and b is now equals to 7
    Console.WriteLine(a = b = 7);
    

    我认为这种分配发生是很自然的。因为 C 语言似乎鼓励 IMO 的速记符号。

    如果您需要更多的可读性和更少的麻烦,那么我会说换行符是一个不错的添加。

    displayReport(
        ReportClass.ReportName = cmbReportName.SelectedValue.ToString());
    

    当每个复合语句位于不同的行时,使您的意图更加清晰。 (但仍然是复合语句)

    或者,首先将正确的部分提取到自己的变量中,例如

    var reportName = cmbReportName.SelectedValue.ToString();
    
    displayReport(ReportClass.ReportName = reportName);
    

    我一直在使用它,我还没有看到有人在阅读时感到困惑。

    【讨论】:

      【解决方案6】:

      我倾向于避免就地分配 - 或者实际上是这样的任何副作用 - 除了一个常见的习惯用法:

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

      (以及用于读取流等的变体)

      我也可以在参数调用中使用对象初始化器,例如

      Foo(new Bar { X=1, Y=2 });
      

      但是分配给现有对象中的属性...嗯,这都是主观的,但它不是我的一杯茶。

      【讨论】:

        【解决方案7】:

        那真的是有效的代码吗?对我来说似乎是一个静态类。

        我猜你会这样使用它:

        displayReport(new ReportClass { ReportName = cmbReportName.SelectedValue.ToString() } )

        【讨论】:

          【解决方案8】:

          完全没问题。他们两个。

          • 自动属性({get; set;} 事物):在 C# 中引入。非常有用的功能。

          • 参数中的赋值:在 C# 中很少使用,但完全合法。基本上,它将赋值运算符 (=) 右侧的表达式的值分配给左侧属性的属性,然后将该值传递给方法。

            这在 C 中更为常见,但我认为没有理由在 C# 中也不允许它。有时它可能有助于提高可读性,有时它会使情况变得更糟。使用常识来决定何时适用。

          【讨论】:

            【解决方案9】:

            我认为这更难维护/更难调试/更难理解代码。我会在调用该方法之前在一行上完成分配。

            ReportClass.ReportName = cmbReportName.SelectedValue.ToString();
            displayReport(ReportClass.ReportName);
            

            我从来都不喜欢复合语句。

            【讨论】:

            • 而且...我也不是 VB 开发人员。 :P
            • 我也不是粉丝,我也更喜欢可读性……但有时我只是懒惰:-)
            猜你喜欢
            • 1970-01-01
            • 2015-02-04
            • 2017-12-17
            • 2011-03-24
            • 1970-01-01
            • 2010-09-29
            • 1970-01-01
            • 2015-03-08
            • 2022-06-18
            相关资源
            最近更新 更多