バックポーティング

C#の言語バージョンと.NET Frameworkバージョンで書いていますが、 C#の新しめの機能を、古いバージョンの.NET上で動かすためには、 いくつかライブラリのバックポーティング(新しいバージョンで追加された機能を、古いバージョンに向けて移植する作業)が必要なものがあります。

ここで問題になるのが、バージョンの混在です。

C# 5.0のasync/awaitを例にとって話しましょう。 まず、以下のように、.NET 4.5で完結している場合にはそもそもバックポーティングが必要なく、何の問題もありません。

.NET 4.5 での async/await

一方で、例えばAsyncBridgeという名前でバックポーティング用のライブラリを用意したとします。 これを使う場合でも.NET 3.5で完結するなら、以下のように特に問題は置きません。

.NET 3.5 での async/await バックポーティング

問題は、.NET 4.5向けライブラリと.NET 3.5向けライブラリの混在です。 .NET 4.5向けのものは標準ライブラリ(System.Threading.Tasks.dll)のTaskクラスを参照し、 .NET 3.5向けのものはバックポーティング(AsyncBridge.dll)のTaskクラスを参照している状態になります。 同名の別実装があると、どちらを参照すればいいのかわからなくなって色々と問題を起こします (回避方法もなくはないものの、基本的にはコンパイルできなくなります)。

この問題の解決にも型フォワーディングが使えます。 以下のように、標準ライブラリへの型フォワーディングを書いたAsyncBridge.dllを用意します。

標準ライブラリとバックポーティングの混在

つまり、以下のような実装が必要になります。

  • .NET 3.5向けに、標準ライブラリをバックポーティング実装を書いた AsyncBridge.dll を作る
    • .NET 3.5アプリからはこれを参照する
  • .NET 4.5向けに、標準ライブラリへの型フォワーディングを書いた AsyncBridge.dll を作る
    • .NET 4.5アプリからはこれを参照する

ちなみに、サンプルでは、async/awaitではなく、もっと実装が簡単なFormatableStringの実装例を書いています。

更新履歴

ブログ