Exploring the .NET CoreFX Part 16: Platform-Specific Builds Using Compile-Time Polymorphism

Exploring the .NET CoreFX Part 16: Platform-Specific Builds Using Compile-Time Polymorphism

Page content

This is part 16 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:

<!-- 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.