匿名实例化语法 - 好还是坏?

Posted

技术标签:

【中文标题】匿名实例化语法 - 好还是坏?【英文标题】:Anonymous Instantiation Syntax - Good or Bad? 【发布时间】:2010-10-17 13:14:06 【问题描述】:

对于我只使用一次实例化对象的快速任务,我知道我可以执行以下操作:

int FooBarResult = (new Foo()).Bar();

我说这对于非一次性对象是完全可以接受的,并且比其他方法更具可读性:

Foo MyOnceUsedFoo = new Foo();
int FooBarResult = MyOnceUsedFoo.Bar();

您使用哪个,为什么? 您会在生产应用程序中使用这种类型的匿名实例化吗? 偏好:带括号“(new Foo()).Bar();”还是没有“new Foo().Bar();”?

(编辑为从 Random 类中抽象出问题)

【问题讨论】:

【参考方案1】:

关于随机数的旁注:事实上,不,您的具体示例 (new Random().Next(0,100)) 是完全不可接受的。生成的随机数会很不均匀。


除此之外,总的来说,两者并没有太大的区别。在这两种情况下,编译器很可能会生成完全相同的代码。您应该使用最易读的案例(长语句可能会损害可读性;更多代码也会这样做,因此您必须根据具体案例进行权衡)。

顺便说一句,如果您选择使用单行大小写,请省略不必要的括号(new MyObject().Method() 可以)。

【讨论】:

如果只生成一个随机数,则没有分布。如果 Random() 有一个糟糕的冷启动行为,那么无论哪种方式,你都不会得到统一的数字。 @danbruc:从技术上讲,有一个发行版,但是是的,我明白你的意思。你说的对。但是我已经看到开发人员多次使用这种方法在循环中生成随机数。我认为在这里提及它非常重要。 完全同意 - 你甚至不应该考虑以这种方式生成多个数字。【参考方案2】:

您可能需要考虑在调试器中使用代码的含义。第二种情况将允许您检查您创建的对象,而第一种情况不会。当然,当您尝试调试代码时,您始终可以退回到第二种情况。

我两种方式都做过,并没有真正的偏好。我更喜欢看起来更易读的东西,这在很大程度上取决于被调用的类和方法的复杂性。

顺便说一句——你可能想选择一个不同的例子。我担心您的观点可能会在讨论生成随机数的最佳方式时丢失。

【讨论】:

【参考方案3】:

如果你只使用一次对象,第一种方法总是更好。

它更短更清晰,因为它明确表明您以后不会使用该对象。

无论如何,它可能会编译成相同的 CIL,因此第二种形式没有优势。

【讨论】:

【参考方案4】:

第一个声明。它更具可读性,代码更少,并且不会留下临时文件。

【讨论】:

【参考方案5】:

第二个是调试友好的,而第一个不是。正因为如此,第二个获胜。

【讨论】:

【参考方案6】:

事实上,第一种方式,创建一个临时的,更具可读性有两个原因:

1) 更简洁

需要阅读的代码更少,没有引入不必要的局部变量,也没有可能的名称与另一个局部变量发生冲突,或者在封闭范围内隐藏任何具有相同名称的变量

2) 它传达了第二种形式没有传达的信息,即该对象正在被临时使用。

阅读它,我知道该实例永远不会再被使用,所以在我用来理解我正在阅读的代码的“心理编译器”中,我不必保留对它的任何引用不仅仅是代码保留了对它的引用。

不过,正如 Mehrdad 所说,使用 Random 类来做这件事并不是一个好主意。

正如他还指出的那样,多余的括号使其不太简洁;除非您处于语言的尘土飞扬的角落,否则请假设有能力的程序员知道该语言的运算符优先级。在这种情况下,即使我不知道运算符优先级,替代解析(在函数返回时调用 new)也是无意义的,因此“明显”的阅读是正确的阅读。

int RandomIndex = (new Random()).Next(0,100);
int RandomIndex = new Random().Next(0,100);

【讨论】:

如果方法采用相当数量的参数,第一个选项的可读性可能会降低。可读性更像是语法而不是数学。规则通常是正确的,但有时打破规则会产生更好的代码。

以上是关于匿名实例化语法 - 好还是坏?的主要内容,如果未能解决你的问题,请参考以下文章

为什么匿名内部类可以实例化并实现抽象方法?lambda表达式是简化了匿名内部类的实现过程吗?

您可以在 .NET 中从 JSON 实例化对象实例吗?

类和对象(类和类的实例化,this,static关键字,封装)

类和对象(类和类的实例化,this,static关键字,封装)

JAVA8 in Action:行为参数化,匿名类及lambda表达式的初步认知实例整理

unity的C#学习——委托事件和匿名方法