Любая причина не использовать `new object(). Foo()`?

При использовании крайне короткоживущих объектов, на которые мне нужно всего лишь вызвать один метод, я склонен привязать вызов метода непосредственно к new. Очень распространенным примером этого является следующее:

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

Дело в том, что я не нуждаюсь в объекте Regex после того, как я сделал одну замену, и мне нравится это выразить как однострочный. Есть ли неочевидная проблема с этой идиомой? Некоторые из моих коллег выразили дискомфорт в этом, но без всякой вещи, которая, по-видимому, была хорошей причиной.

(Я отметил это как С# и Java, так как вышеупомянутая идиома является общей и пригодной для использования на обоих языках.)

Ответ 1

Эта конкретная модель в порядке - я использую ее сам по себе.

Но я бы не использовал этот шаблон, как у вас в вашем примере. Есть два альтернативных подхода, которые лучше.

Лучший подход: Использовать статический метод Regex.Replace(строка, строка, строка). Нет причин для того, чтобы обмануть ваш смысл синтаксисом new -style, когда доступен статический метод, который делает то же самое.

Лучший подход: Если вы используете тот же статический (не динамически сгенерированный) Regex из того же метода, и вы вызываете этот метод много, вы должны сохранить объект Regex как личное статическое поле в классе, содержащем метод, поскольку это позволяет избежать разбора выражения при каждом вызове метода.

Ответ 2

Я не вижу в этом ничего плохого; Я делаю это довольно часто сам.

Единственное исключение из правила может быть для целей отладки, иногда необходимо иметь возможность видеть состояние объекта в отладчике, что может быть затруднено в одном слое, как это.

Ответ 3

Если после этого вам не нужен объект, я не вижу проблемы - я тоже делаю это время от времени. Однако это может быть довольно сложно определить, поэтому, если ваши коллеги выражают дискомфорт, вам может потребоваться ввести его в переменную, чтобы в команде не было никаких трудностей. На самом деле вам не больно.

Ответ 4

Вам просто нужно быть осторожным, когда вы цепляете методы объектов, которые реализуют IDisposable. Выполнение однострочной цепочки не оставляет места для вызова Dispose или использования блока {...}.

Например:

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

Нет переменной экземпляра для вызова Dispose.

Тогда есть потенциал, чтобы запутать намерение, причинить боль, а не улучшать читаемость и сделать его более сложным для изучения значений во время отладки. Но это все проблемы, характерные для объекта, ситуации и количества прикованных методов. Я не думаю, что есть одна причина, чтобы избежать этого. Иногда это делает код более кратким и читаемым, а в других случаях он может повредить некоторые из упомянутых выше причин.

Ответ 5

Пока вы уверены, что объект больше не нужен (или вы не создаете несколько экземпляров идентичного объекта), тогда нет проблем с ним.

Если остальная часть вашей команды не устраивает его, вы, возможно, захотите переосмыслить решение. Команда должна установить стандарты, и вы должны следовать им. Быть последовательным. Если вы хотите изменить стандарт, обсудите его. Если они не согласны, тогда упасть в линию.

Ответ 6

Я думаю, что все в порядке, и я бы приветствовал комментарии/причины об обратном. Когда объект не является короткоживущим (или использует неуправляемые ресурсы - то есть COM), тогда эта практика может вызвать у вас проблемы.

Ответ 7

Проблема - читаемость.

Помещение "прикованных" методов на отдельной строке, по-видимому, является предпочтительным соглашением с моей командой.

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

Ответ 8

Одна из причин избежать этого стиля заключается в том, что ваши коллеги могут захотеть осмотреть объект в режиме отладки. Если вы сочтете похожий экземпляр, читаемость значительно снизится. Например:

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

Обычно я предпочитаю использовать статический метод для конкретного примера, который вы упомянули.

Ответ 9

Единственная потенциальная проблема, которую я мог видеть, - если по какой-то причине новое Regex было NULL, потому что оно не было создано правильно, вы получили бы исключение Null Pointer. Тем не менее, я очень сомневаюсь, что поскольку Regex всегда определяется...

Ответ 10

Если вам не нужен объект, на который вы ссылаетесь, этот знак должен быть статическим.

Ответ 11

В С# я, вероятно, написал бы метод расширения, чтобы обернуть регулярное выражение, чтобы я мог написать

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+", " ");
        }
    }
}

Мне кажется, что это намного легче читать, чем ваш оригинальный пример. Он также вполне можно использовать повторно, поскольку разделение символов новой строки является одним из наиболее распространенных видов деятельности.