编码风格:表达式内的赋值?

时间:2011-02-17 17:04:19

标签: c# coding-style

快速询问此社区的见解:哪一个更受欢迎?


选项①

// How many spaces are there in the beginning of string? (and remove them)
int spaces = text.Length;
text = text.TrimStart(' ');
spaces -= text.Length;
  • 优势:在单独的行上进行分配,因此副作用是明确的
  • 缺点:第一行本身看起来没有意义;你必须注意第三行才能理解它

选项②

// How many spaces are there in the beginning of string? (and remove them)
int spaces = text.Length - (text = text.TrimStart(' ')).Length;
  • 优势:语句在执行的计算方面有意义
  • 缺点:分配有点隐藏在表达式中;副作用可以忽略

6 个答案:

答案 0 :(得分:36)

我不喜欢他们中的任何一个。编写清晰代码的一些准则:

  • 变量的含义在变量的整个生命周期内应保持不变。

选项(1)违反本指南;变量“spaces”被注释为“文本中有多少个空格”,但它实际上并没有这个含义!它通过在文本中作为字符的数量开始其生命周期,并将其生命周期结束为文本中以前的空格数。它在整个生命周期中意味着两种不同的东西,它们都不是所记录的意思。

  • 表达式语句只有一个副作用。 (“表达式语句”是由单个表达式组成的语句;在C#中,合法语句表达式是方法调用,对象构造,增量,减量和赋值。)

  • 表达式没有副作用,除非表达式是表达式语句的单个副作用。

选项(2)显然违反了这些准则。做多个副作用的表达式语句很难推理,它们很难调试,因为你不能把断点放在你想要的地方,这一切都很糟糕。

我会重写你的片段以遵循这些准则。

string originalText = text;
string trimmedText = originalText.TrimStart(' ');
int removedSpaces = originalText.Length - trimmedText.Length;
text = trimmedText;

每行一个副作用,每个变量在整个生命周期中都意味着完全相同的东西。

答案 1 :(得分:12)

我会做选项1b:

int initial_length = text.Length;
text = text.TrimStart(' ');
int spaces = initial_length - text.Length;

当然,它几乎与选项一重复,但它更清晰一些(稍后您可能需要字符串的初始长度)。

答案 2 :(得分:1)

我个人更喜欢选项1.尽管选项2更简洁,并且工作正常,但我想到了在我继续前进之后必须保持这一点的人,我想让我的代码尽可能易于理解。我可能知道作为表达式的赋值会计算分配的值,但下一个人可能不会。

答案 3 :(得分:1)

超载怎么样?

public static string TrimStart(this string s, char c, out int numCharsTrimmed) 
{
    numCharsTrimmed = s.Length;
    s = s.TrimStart(c);
    numCharsTrimmed -= s.Length;    
}

答案 4 :(得分:0)

选项①全天。它是可读的。选项②更难维护。

答案 5 :(得分:-3)

从您的问题本身的角度来看,我会说不要在表达式中进行分配,因为它并不是所有语言都支持,例如Python,所以如果你想在自己的个人编码风格中保持一致,那么你可以坚持传统的任务。