Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting rid of precompiler directives in C#

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.


CONCLUSION

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.

like image 656
Sergi Papaseit Avatar asked Mar 18 '11 14:03

Sergi Papaseit


People also ask

How do you stop Ifndef?

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.

What is pre processor directive in C?

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.

What does the #include precompiler directive do?

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.

Why preprocessor directives are needed in the beginning of C program?

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.


1 Answers

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?

like image 165
Oded Avatar answered Nov 02 '22 08:11

Oded