有什么理由不使用`new object()。foo()`?

时间:2010-12-21 18:57:46

标签: c# java new-operator

当使用非常短暂的对象时,我只需要调用一个方法,我倾向于将方法调用直接链接到new。一个非常常见的例子如下:

string noNewlines = new Regex("\\n+").Replace(" ", oldString);

这里的要点是,在我完成一次更换之后,我不需要Regex对象,我希望能够将其表达为单行。这个成语有什么不明显的问题吗?我的一些同事对此表示不满,但没有任何看起来像是一个很好的理由。

(我把它标记为C#和Java,因为上面的习语很常用,并且可以在两种语言中使用。)

11 个答案:

答案 0 :(得分:6)

这种特殊模式很好 - 我偶尔会自己使用它。

但我不会像你的例子那样使用这种模式。有两种更好的替代方法。

更好的方法:使用静态方法Regex.Replace(string,string,string)。当静态方法可用于执行相同操作时,没有理由使用new样式语法来混淆您的意思。

最佳方法:如果您使用相同方法的相同静态(非动态生成)Regex,并且您经常调用此方法,则应将Regex对象存储为私有静态字段在包含该方法的类上,因为这可以避免在每次调用方法时解析表达式。

答案 1 :(得分:5)

我没有看到任何错误;我自己经常这样做。

规则的唯一例外可能是出于调试目的,有时需要能够在调试器中看到对象的状态,这在单行内容中可能很难。

答案 2 :(得分:2)

如果您之后不需要该物品,我不会发现问题 - 我也会不时地自己做。然而,它很难被发现,所以如果你的同事表达不适,你可能需要把它变成一个变量,所以团队没有任何难过的感觉。真的没有伤害你。

答案 3 :(得分:2)

当您链接实现IDisposable的对象的方法时,您必须要小心。做一个单行链并没有真正留下调用Dispose或使用{...}块的空间。

例如:

DialogResult result = New SomeCfgDialog(some_data).ShowDialog();

没有可以调用Dispose的实例变量。

然后有可能混淆意图,伤害而不是提高可读性,并使调试时检查值变得更加困难。但这些都是特定于对象和情况以及链接方法数量的问题。我认为没有一个理由可以避免它。有时这样做会使代码更简洁和可读,有时可能会因上述某些原因而受到伤害。

答案 4 :(得分:1)

只要您确定不再需要该对象(或者您没有创建相同对象的多个实例),那么它就没有问题。

如果团队的其他成员对此不满意,您可能需要重新考虑这个决定。团队应该设定标准,你应该遵循它们。始终如一。如果您想更改标准,请进行讨论。如果他们不同意,那就排好了。

答案 5 :(得分:1)

我认为没关系,欢迎评论/理由相反。当对象不是短暂的(或使用非托管资源 - 即COM)时,这种做法可能会让你陷入困境。

答案 6 :(得分:1)

问题在于可读性。

将“链式”方法放在一个单独的行上似乎是我团队的首选约定。

string noNewlines = new Regex("\\n+")
                             .Replace(" ", oldString);

答案 7 :(得分:1)

避免这种风格的一个原因是你的同事可能想要以调试模式检查对象。如果复合相似的实例化,可读性会下降很多。例如:

String val = new Object1("Hello").doSomething(new Object2("interesting").withThis("input"));

一般来说,我更喜欢对你提到的具体例子使用静态方法。

答案 8 :(得分:0)

我能看到的唯一潜在问题是 - 如果出于某种原因,新的正则表达式为NULL,因为它没有正确实例化,你会得到一个空指针异常。但是,我非常怀疑,因为Regex总是被定义......

答案 9 :(得分:0)

如果您不关心调用该方法的对象,那表明该方法应该是静态的。

答案 10 :(得分:0)

在C#中,我可能会编写一个扩展方法来包装正则表达式,这样我就可以写了

string noNewlines = oldString.RemoveNewlines();

扩展方法看起来像

using System.Text.RegularExpressions;

namespace Extensions
{
    static class SystemStringExtensions
    {
        public static string RemoveNewlines(this string inputString)
        {
            // replace newline characters with spaces
            return Regex.Replace(inputString, "\\n+", " ");
        }
    }
}

我发现这比原始示例更容易阅读。它也是可以重复使用的,因为剥离换行符是更常见的活动之一。