I've been asked to maintain some not-as-legacy-as-I-would-like code, and it is riddled with compiler directives, making it pretty much unreadable and almost as maintainable. Case in point:
#if CONDITION_1
protected override void BeforeAdd(LogEntity entity)
#else
protected override void BeforeAdd(AbstractBusinessEntity entity)
#endif
{
#if CONDITON_1
entity.DateTimeInsert = DateTime.Now;
#else
((LogEntity) entity).DateTimeInsert = DateTime.Now;
#endif
base.BeforeAdd(entity);
}
using
directives are even prettier:
#if CONDITION_1
using CompanyName.Configuration;
#endif
#if CONDITION_2||CONDITION_1
using CompanyName.Data;
using CompanyName.Data.SqlBuilders;
#else
using CompanyName.Legacy.Database;
using CompanyName.Legacy.Database.SQLBuilders;
using CompanyName.Legacy.Database.SQLBuilders.parameterTypes;
#endif
I thought I'd give the ConditionalAttribute
a go but that won't quite work in this situation
Is there any way I can work my way out of this compiler directive nightmare?
The code is compiled against .NET 3.5
.
UPDATE:
Oded answered suggesting removing the compiler directives around the BeforeAdd
method thus overloading it. Unfortunately that won't work since both methods are supposed to be overriding an AbstractBusiness
class which provides two different implementations depending on which assemblies end up being included:
protected virtual void BeforeAdd(TEntity entity) {}
or
protected virtual void BeforeAdd(AbstractBusinessEntity entity) {}
This code gets its dependencies from a set of libraries de company created some time in the past and have been "upgrading" ever since. They now have 4 different versions of that set of libraries with colliding namespaces and differing implementations. All in the name of "backwards compatibility" with applications that use the (very) old versions.
I ended up choosing @Oded's answer because it makes the most sense as a general approach (K.I.S.S. and all that). I could not use it in this case though; what you see here is just the tip of the iceberg. I wouldn't want to K.I.S.S. this code if it paid me.
The #ifndef must be ended with the #endif directive of the C Programming Language. #else directive: If the #ifndef does not accept then else code statements will be printed which are actually used in including the specific which is defined.
It is a pre-process of execution of a program using c/c++ language. To initialize a process of preprocessor commands, it's mandated to define with a hash symbol (#). It can preferably be the non-blank character, and for better readability, a preprocessor directive should start in the first column.
Preprocessor programs provide preprocessor directives that tell the compiler to preprocess the source code before compiling. All of these preprocessor directives begin with a '#' (hash) symbol. The '#' symbol indicates that whatever statement starts with a '#' will go to the preprocessor program to get executed.
Preprocessor directives, such as #define and #ifdef , are typically used to make source programs easy to change and easy to compile in different execution environments. Directives in the source file tell the preprocessor to take specific actions.
In the first case, it looks like you could simply have several overloads of the method instead of this construct. Overload resolution should take care of things at this point.
In the second case (using directives) - you can alias some of the directives and include all of them, using the alias where needed. What happens when all namespaces are included? Any name collisions?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With