Can I have global preprocessor definitions in a C # library?

In C #, you can have conditional compilation using macros similar to C / C ++ syntax. This will allow you to do the following:

#define MYMACRO .... #if MYMACRO //some C# code logic #else //some other C# code logic 

I need to define some macros in a highlighted file in a C # library project, and I need these macros to be visible in the whole library after definition. The problem is that the above code only works for one file.

Another way I know to get around this is to add macros to the build command. This will take care of defining macros for the whole .dll , and I will do the #if - #else wherever I want inside the library. The problems with this approach are that I want to be able to easily support macros. Having them in a file inside a project would be ideal. I would also like to have some comments inside so that I know what each macro does. This does not apply if I need to pass macros as build parameters. Another reason is that you can enable or disable the macro by simply commenting on it and exploring the behavior.

Is there a decent way to achieve my requirement? I would prefer not to deal with build automation tools such as MSBuild , NAnt or something like that, but if there is no other way, I would appreciate the advice that you consider the best choice.

+6
source share
3 answers

I also recommend putting macros in project parameters (csproj file), as @Hans Passant suggests.

If you need documented definitions, you can add a documentation file to the solution explaining what the settings mean.

If there are not many options, you can define a new project configuration for each of them. This will allow you to pre-configure the required #defines list for each option, and then simply switch between them from the configuration list box on the toolbar. If you want to temporarily disable one parameter, you can duplicate the current configuration and delete #define, and then delete the configuration later when you tested it.

The next option, which I can offer to make it β€œeasier” (by combining settings and documents into a single file, as you suggested), will use a simple text file (settings + comments) to set up the project, and spend 15 minutes on a fast C # application for reading this file and write the parameters that it contains in the .csproj file - this is just XML, so it should be a trivial writing application. You can easily configure this file and run the updater application to configure project settings. If you will do something often, spend 30 minutes on it and add a user interface with checkboxes to make it easier to choose settings.

The concept you are describing sounds rather strange. The point of the library is usually that you have one standardized piece of code that can be used by many clients, so changing these definitions to reorganize the entire library is not something I would expect to do very often. Perhaps you have good reasons , but it might be worth considering why you need to solve this #define problem.

(for example, if you have many clients who need different versions of the "library", the best option would be to use the configurations (described above) that allow you to create all the necessary options in a batch assembly. If you just try many different algorithms / methods, you can redo library pieces to limit the impact of most #defines on a single .cs file so that they no longer need a global? Maybe the library should not be in the same dll, or a plug-in architecture is needed so you can choose " Modules ", which are included in the library).

+2
source

You #define them for the whole project with the tab Project + Properties, Build, "Conditional Compilation Symbols". This sets the <DefineConstants> element in the project file. You override this property with msbuild by providing it with the / property: DefineConstants = "MYMACRO" parameter.

+5
source

The C # preprocessor directives do not work the same as the C preprocessor directives. The most important thing for you is the lack of the #include equivalent. This is not required under normal circumstances because C # does not have (or does not need) header files. I don’t think you want to, unless you somehow create your own preprocessor or read the file using #define and turn them into msbuild parameters.

But I think it will be easier for you to use a more object-oriented approach: encapsulate various approaches in classes and use them. To indicate which one to use, you can use dependency injection. This means that you will have to send the DI library along with your library, but I think it's worth paying.

In addition, this approach would alleviate the conditional compilation problem: specifying a different set of characters can lead to a build failure in unexpected ways.

+2
source

Source: https://habr.com/ru/post/907154/


All Articles