7

While I was working on some of older code in C#, I encountered a code which irked me.

Without much ado, it goes something like this:

private string foo(string _text)
{
   /* some manipulation on _text */
   return _text = Server.HtmlDecode(_text);
}

It's the last line which irks me; I'm from C background, and I can understand that the code is in effect trying to return a decoded _text variable. Also the value of an assignment operator is the left operand, so I can see it.

Yet I still find it irksome.

Is it a ordinate practice in C# that I need to get accustomed to?

To me the last line should simply be

return Server.HtmlDecode(_text);

and not be an assignment expression. Is there a deeper C# feature which I'm not aware of?

4

5 回答 5

13

当我在 C# 中处理一些较旧的代码时,我遇到了一个让我恼火的代码。

这里有许多令人讨厌的问题。让我们把它们都列出来。

private string foo(string _text)
{
   /* some manipulation on _text */
   return _text = Server.HtmlDecode(_text);
}

这是让我恼火的最后一句话

评论也令人厌烦。局部变量很便宜。无需抹去 的原始值_text。相反,创建一个新的局部变量并对其进行操作。这样,当您在方法中的任何位置进行调试时,您都可以知道原始参数是什么。(请记住,在变量被覆盖的那一刻,原始参数可能有资格进行垃圾收集,因此可能永远丢失。)

不要在没有充分理由的情况下改写形式参数。它使调试变得更加困难。

赋值运算符的值是左操作数,所以我可以看到它。

在这种情况下这是正确的,但总体上是微妙的错误;C#中赋值运算符的值是操作数转换为与左侧相关的类型后的值。请记住,左侧可能没有值;它可能是只写属性。

这是我需要习惯的 C# 中的常规练习吗?

这里有一个标准做法,是的。这种用法的奇怪之处在于(1)选择的变量是正式的,以及(2)赋值与return.

C# 中的标准做法是这样说:

string decoded = Server.HtmlDecode(_text);
return decoded;

现在您可能想知道与您的建议相比,这样做的引人注目的好处是什么:

return Server.HtmlDecode(_text);

答案是:在 Visual Studio 2013 之前,调试器中没有工具来检查方法调用的返回值!因此,如果您想查看HtmlDecode调试时返回的值是什么,您有以下选择:

  • 在汇编级别调试并查看 EAX 的内容
  • 进入HtmlDecode并检查其状态
  • 跳出当前方法并检查分配给的返回值
  • 将结果分配给其他无用的局部变量,然后在调试器中检查局部变量

由于前三个是可怕的,而最后一个很容易,这就是许多 C# 程序员习惯做的事情。

如果你这样做然后使用生成的本地,C# 编译器知道这是一种常见的做法,并故意抑制“你写到本地然后从不读取”警告。如果本地有一个常量写入它,它只会发出警告,在这种情况下,您已经知道它在编译时是什么,并且通常不需要在调试器中检查它。

希望现在 VS2013 终于支持这个经常被要求的功能,这种模式会逐渐消失。

于 2013-08-26T16:43:23.893 回答
3

此语句是多余的,而不是C# 实践。

在 ReSharper 处于活动状态时这样做也会发出警告

分配的值未在任何执行路径中使用

正如您所提到的,这段代码确实是最佳实践

return Server.HtmlDecode(_text);

此外,由于解码是 _text 操作的一部分,因此将分配和返回语句分开也是有效的,以将逻辑保持在同一块中:

/* Other manipulations on _text */
_text = Server.HtmlDecode(_text);

return _text;
于 2013-08-26T16:04:53.680 回答
0

不,这是一件愚蠢的事情,它以将更多代码塞进一行的名义牺牲了可读性。这几乎总是一件坏事。

在这种情况下,它实际上没有任何作用。_text是方法的参数,在方法体中更改它没有任何作用。传递给该方法的字符串不会被修改。

于 2013-08-26T15:49:02.663 回答
0

不,在这种情况下没有更深层次的 C# 功能,在return语句中进行赋值是毫无意义的。它只会使遵循代码应该做的事情变得更加困难。

与您建议的唯一区别是将解码后的值分配给_text变量,但是由于不再使用该变量,因此方法结束时它的值是什么并不重要。该参数是方法内部的局部变量,不会影响方法外部的任何内容。

于 2013-08-26T15:55:30.843 回答
0

他们有相同的结果。最常见的是后者,或者:

_text = Server.HtmlDecode(_text);
return _text;

(我喜欢上面的或return Server.HtmlDecode(_text);,但不是你正在阅读的代码中的方式)

于 2013-08-26T15:49:58.180 回答