23

I'm playing with adding Gtk# GUI to a Windows.Forms application. I need a way to isolate Mono-specific code in Program.cs since I'd like to avoid creation of a separate .sln/.csproj. In C/C++/Objective-C projects, I'd do something similar to #ifdef __APPLE__ or #ifdef _WIN32.

C# appears to have the #if command.

What is the typical way to isolate Mono-specific code, or Visual Studio-specific code?

Ivan Vučica
  • 9,529
  • 9
  • 60
  • 111
  • Please don't use #if, check this instead on how to make portable assemblies: http://stackoverflow.com/questions/721161/how-to-detect-which-net-runtime-is-being-used-ms-vs-mono – skolima Jul 25 '12 at 12:47
  • @skolima the OP wants to make a compile time decision, not a run-time decision. `#if` and `[ custom attributes ]` are the only way. – Jesse Chisholm Dec 04 '18 at 23:42

1 Answers1

37

You can define a symbol using #define and check against it, using #if and #else.

You can also pass the symbol to the compiler using the /define compiler option.

See the complete list of C# Preprocessor directives here.

#define MONO // Or pass in "/define MONO" to csc 

#if MONO
 //mono specific code
#else 
 //other code
#endif

According to this SO answer, the mono compiler defines a __MonoCS__ symbol, so the following would work:

#if __MonoCS__
 //mono specific code
#else 
 //other code
#endif

The recommended method that the Mono "Porting to Windows" guide, as detailed in this answer by @Mystic, is:

public static bool IsRunningOnMono ()
{
    return Type.GetType ("Mono.Runtime") != null;
}

This, of course, is a runtime check, versus the compile time checks above so may not work for your specific case.

Community
  • 1
  • 1
Oded
  • 489,969
  • 99
  • 883
  • 1,009
  • Is there such a built-in directive that exists only on VS or only on Mono? I'm trying NOT to change the project file :-) – Ivan Vučica Mar 01 '11 at 20:11
  • 2
    @Ivan - according to [this](http://stackoverflow.com/questions/329043/how-can-i-conditionally-compile-my-c-for-mono-vs-microsoft-net/329072#329072) SO answer, it defines `__MonoCS__`. – Oded Mar 01 '11 at 20:15
  • 1
    I have no idea how you managed to find that, I took my time to find the answer and turned up nothing :-) I'll go the `Type.GetType()` route, mentioned in that answer. Thanks! – Ivan Vučica Mar 01 '11 at 20:21
  • 1
    …except that would mean MSVC would still see references to GTK code. So `#if __MonoCS__` it is. Thanks again! – Ivan Vučica Mar 01 '11 at 20:34
  • Downvoted. http://stackoverflow.com/questions/721161/how-to-detect-which-net-runtime-is-being-used-ms-vs-mono is a much better way, as the same assembly will work on both platforms. – skolima Jul 25 '12 at 12:48
  • 1
    @skolima - Added details of linked answer. However, you need to consider that some use cases will require compile time resolution versus the runtime resolution detailed in the answer you linked to. – Oded Jul 25 '12 at 13:11
  • I still prefer to extract the platform specific code into a helper assembly and choose one or the other version during runtime. It's much less confusing for the user when there's only a single version to download/deploy. – skolima Jul 25 '12 at 13:55
  • @skolima - I am not arguing that your preference is not the better option, just that for _some_ use cases, determining this at runtime is not the right choice. – Oded Jul 25 '12 at 14:00