Exploring the .NET CoreFX Part 16: Platform-Specific Builds Using Compile-Time Polymorphism
Exploring the .NET CoreFX .net core csharp
Published: 2015-03-01
Exploring the .NET CoreFX Part 16: Platform-Specific Builds Using Compile-Time Polymorphism

This is part 16/17 of my Exploring the .NET CoreFX series.

While .NET has historically been limited to Windows machines, Mono notwithstanding, the introduction of the cross-platform .NET Core runtime has introduced the possibility of running .NET Core applications on Unix machines. With this possibility, developers may have the need of writing platform-specific code.

One way to write platform-specific code is:

  1. Define a conceptual base class which will have an identical name and methods across all platforms. This does not need to be a C# interface, as we will be using compile-time rather than run-time polymorphism.
  2. Provide an implementation of this class for each target platform.
  3. Use build-time conditions to include the platform-specific class based on target compilation platform.

An example from the .NET Core is the System.Console.ConsolePal class from the System.Console library. The library includes two implementations of this class:

  1. ConsolePal.Unix.cs, which provides a Unix-compatible implementation of the ConsolePal class
  2. ConsolePal.Windows.cs, which provides a Windows-compatible implementation of the ConsolePal class

The project file for this library, System.Console.csproj, then selects the appropriate file to build based on the target platform at compile time:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<!-- System.Console.csproj -->
...
<ItemGroup Condition="'$(OS)' == 'Windows_NT'">
    <Compile Include="System\ConsolePal.Windows.cs" />
    ...
</ItemGroup>
<ItemGroup Condition="'$(OS)' == 'Unix'">
    <Compile Include="System\ConsolePal.Unix.cs" />
    ...
</ItemGroup>

The advantage of this approach is that it has no run-time polymorphism overhead and thus provides maximum performance. The disadvantage of this approach is that the resulting binaries are platform-specific.

Recommendations

  • Avoid writing platform-specific .NET code unless it is completely unavoidable.
  • Consider using compile-time polymorphism to implement platform-specific code.