Вопрос

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

родовое слово

Директивы using еще красивее:

родовое слово

Я подумал, что дам ConditionalAttribute попробовать, но в данной ситуации это не сработает

Есть ли способ выбраться из этого кошмара директив компилятора?

Код скомпилирован в соответствии с .NET 3.5.

ОБНОВЛЕНИЕ:
Одед ответил, предлагая удалить директивы компилятора вокруг метода BeforeAdd, что приведет к его перегрузке. К сожалению, это не сработает, поскольку оба метода должны переопределять класс AbstractBusiness, который предоставляет две разные реализации в зависимости от того, какие сборки в конечном итоге будут включены:

родовое слово

или

родовое слово

Этот код получает свои зависимости от набора библиотек, созданных компанией когда-то в прошлом и с тех пор "обновляющихся". Теперь у них есть 4 разные версии этого набора библиотек с конфликтующими пространствами имен и разными реализациями. И все во имя «обратной совместимости» с приложениями, использующими (очень) старые версии.


< sizesЗАКЛЮЧЕНИЕ

В итоге я выбрал ответ @Oded, потому что он имеет наибольший смысл в качестве общего подхода ( KISS и все такое). Однако я не мог использовать его в этом случае; то, что вы видите здесь, - это лишь верхушка айсберга. Я бы не хотел, чтобы K.I.S.S. этот код, если он мне заплатил.

Это было полезно?

Решение

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

Во втором случае (с использованием директив) вы можете задать псевдоним для некоторых директив и включить их все, используя псевдоним там, где это необходимо.Что произойдет, если будут включены все пространства имен?Есть ли конфликты имен?

Другие советы

Я бы сказал, что проблема не в этом классе. Этот урок - всего лишь симптом. Проблема в базовом классе, вызывающем BeforeAdd. Если вы можете там провести рефакторинг, тогда вам не понадобятся условные компиляции.

Если у вас есть конфликтующие имена и пространства имен, вы можете обойти это с помощью ключевого слова using (не для сборок).

Итак, вы можете сделать что-то вроде

родовое слово

Я также думаю, что проблема в базовом классе, а не в этом классе как таковом.

В этом случае вы можете обойти эту ерунду, используя либо адаптацию, либо интерфейс.

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

родовое слово

затем в базовом классе вашего агрегатора:

родовое слово

затем в вашем подклассе:

родовое слово

Теперь вы можете адаптировать другие объекты к IEntity, реализовав этот интерфейс.

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

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

Вы изолируете код CONDITION_1 примерно так:

родовое слово

Мне в данном случае это не нравится из-за повторения кода. Вы можете помочь в этом с помощью ключевого слова using:

родовое слово

Судя по тому, что я вижу, похоже, что исходный разработчик не имел никакого представления о наследовании и полиморфизме.Это немного сложно сказать по коду, но кажется, что LogEntity и AbstractBusinessEntity имеют общие свойства.Есть ли модель наследования или это два совершенно не связанных класса?Если они не связаны, не могли бы вы создать модель наследования или интерфейс, который они оба могут реализовать?Может помочь, если вы вставите классы.

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

Не знаю, практично ли это, но я бы создал ветки в моем DVCS, Mercurial, чтобы справиться с этим.

У меня будет две ветки в игре и третья временно, пока я исправляю ошибки / добавляю общий код.

Вот как я бы создал начальные версии:

родовое слово

Чтобы исправить ошибки только в одном из них:

родовое слово

Чтобы исправить распространенные ошибки:

родовое слово

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top