Archive for 11月 2014
C#の言語バージョンと.NET Frameworkバージョン
C#の言語機能のバージョンと.NET Frameworkのバージョン(実行環境には大して手が入っていないので、おおむね標準ライブラリのバージョンのこと。どのクラス・どのメソッドが使えるか)は、基本的には独立しています。なので、C#の新機能の多くは古い.NET Framework上でも動きます。
「多くは」であって、「全て」ではないわけですが。ここが今日の主題。どういう機能は、どういう理由で動かないか。どうやっても動かないのか、それとも、動かしようがあるのか。ということについて書いていきます。
サンプルコードはこちらに: https://github.com/ufcpp/UfcppSample/tree/master/LanguageAndFrameworkVersion
古いバージョンで動くかどうか
.NET Framework 1.0/1.1 はもうサポートが切れているので調査対象外(Visual Studio上でもターゲット フレームワークに選べないので)。つまり、以下の表で、「2.0で動く」となっているものは「どこでも動くもの」。
C# 3.0
Visual Studio 2008, .NET Framework 3.5と同時期リリース。
機能 |
どのバージョンで動くか |
変数の型推論 |
2.0 |
配列の型推論 |
|
オブジェクト初期化子 |
|
コレクション初期化子 |
|
プロパティの自動実装 |
|
ラムダ式 |
|
クエリ式 † |
|
部分メソッド |
|
匿名型 |
|
拡張メソッド |
3.5※ |
※ … 2.0で動かすすべあり
† … 補足あり
C# 4.0
Visual Studio 2010, .NET Framework 4と同時期リリース。
機能 |
どのバージョンで動くか |
引数の規定値と名前付き引数 |
2.0 |
変性(genericのin/out型注釈)† |
|
dynamic |
4.0× |
† … 補足あり
× … dynamicは古いバージョンの.NET Frameworkで動かすのがほぼ無理臭い唯一の機能かも。
C# 5.0
Visual Studio 2012, .NET Framework 4.5と同時期リリース。
機能 |
どのバージョンで動くか |
async/await |
4.5 ※1 |
Caller Info |
4.5 ※2 |
※1 … 4で動かすすべあり
※2 … 2.0で動かすすべあり
C# 6.0
おそらくVisual Studio 2015, .NET Framework 4.6と同時期リリース予定。
機能 |
どのバージョンで動くか |
自動実装プロパティに対する初期化子 |
2.0 |
get-onlyの自動実装プロパティ |
|
式形式の関数メンバー定義 |
|
using static |
|
null条件演算子 |
|
インデックス初期化子 |
|
nameof演算子 |
|
例外フィルター |
|
構造体の引数なしコンストラクター |
|
文字列補間 |
2.0 ※1 |
拡張メソッドを使ったコレクション初期化子 |
3.5 ※2 |
catch句/finally句内でのawait演算子利用 |
4.5 ※3 |
※1 … 書き方によっては4.6でないと動かなくなる
※2 … 拡張メソッドの制限そのまま。拡張メソッドを2.0で動かす方法はあるので、それを使えば2.0
※3 … 同様に、await演算子の制限。4で動かすすべあり
動かし方、補足など
前節の表で、2.0で動くとなっているものは、要は、ライブラリ依存がなくて、単純にC#コンパイラーだけの仕事で実現できる機能です。
逆に、特定のバージョンに依存しているものは、そのバージョンで追加されたクラスに依存しています。
なのに、古いバージョンの.NET Frameworkでも「動かすすべがある」というのはどういうことかというと、あるクラスに依存するといっても厳密なチェックをしているわけではなく、同じ名前・同じ機能のクラスを自前で実装すれば動きます。なので、原理的に言うと、どの機能でも.NET Framework 2.0で動かせるんですが… C#機能ごとに、その依存するクラスを実装する大変さが全然違うので、現実的には全部とはいかないでしょう。
拡張メソッド、Caller Info
かなり簡単なのがこの2つ。この2つは、単にメソッドや引数に属性が付くだけのものです。
- 拡張メソッド → ExtensionAttribute(System.Runtime.CompilerServices名前空間)
- Caller Info → CallerFilePathAttribute, CallerLineNumberAttribute, CallerMemberNameAttribute(System.Runtime.CompilerServices名前空間)
属性の実装は簡単。例えば以下のようなコードで終わり。
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)]
public
sealed
class
ExtensionAttribute : Attribute
{
}
}
クエリ式
System.Linq名前空間のクラスがなくて動くの?と一瞬思うかもしれませんが、SelectとかWhereとかを自前実装すれば使えます。そんなに難易度も高くないものなので割とちょろい。
あと、SelectとかWhereは、普通のインスタンス メソッドでも拡張メソッドでもどちらでもOKです。
変性(genericのin/out型注釈)
インターフェイスやデリゲートを定義する側は何の問題もなく、.NET Framework 3.5以前の上で動くんですが…
残念なのは、標準ライブラリ(BCL: Base Class Library)中のクラスにちゃんとした変性注釈がついたのは.NET Framework 4からです。つまり、以下のようなコードを書けるのは、結局、.NET Framework 4以降のみ。
List<string> x = new
List<string> { “one”, “two”, “three” };
IEnumerable<object> y = x;
dynamic
dynamicが使っているのはSystem.Dynamic名前空間以下のクラスなんですが… こいつの自前実装はさすがにちょっと…
実質的に、古い.NET Framework上で動かしようがない唯一の機能かも。もちろん、monoの実装をとってきて使うなどすれば、無理ではないはず。
async/await
これも、.NET Framework 4.5で入ったTaskクラスに対する拡張が必須になります。自前で実装できる規模も超えていると思います。
ただ、こちらには多少救いがあって、マイクロソフトの.NETチームは、.NET 4と.NET 4.5の差分にあたるものを、NuGetパッケージとして公開してくれています。その中にはasync/awaitに関するものもあって、Microsoft.Bcl.Asyncという名前のパッケージになっています。これを使えば、async/awaitを.NET Framework 4の上で動かすことはできます。しかし、あくまで4から4.5の間の差分で、3.5以前には対応できません。
文字列補間(string interpolation)
(現行のVisual Studio 2015 Previewとは文法が変わることが確定しているんですが、新しい方の(今は動かない)文法で説明します)
文字列補間は、普通に使う分にはただのstring.Formatへの展開なので、.NET Framework 2.0上でも動きます。
var s = $”{x}, {y}”;
このsはstring型で、この行は以下のように展開されます。
var s = string.Format(“{0}, {1}”, x, y);
ただ、この文法だとカルチャー指定付きでのFormatなどができないので、別途、以下のように書けるバージョンが追加される予定です。
IFormattable f = $“{x}, {y]”;
この場合、以下のように展開されます。
IFormattable f = new System.Runtime.CompilerServices.FormattedString(“{0}, {1}”, x, y);
この、FormattedStringクラスは、.NET Framework 4.6で追加される予定のクラスです。それほど複雑ではなく、自作は簡単でしょう。以下のような内容です。
namespace System.Runtime.CompilerServices
{
public
struct
FormattedString : System.IFormattable
{
private
readonly
String format;
private
readonly
object[] args;
public FormattedString(String format, params
object[] args)
{
this.format = format;
this.args = args;
}
public
String Format => this.format;
public
object[] Args => this.args;
string
IFormattable.ToString(string ignored, IFormatProvider formatProvider)
{
return
String.Format(formatProvider, format, args);
}
}
}
また、おそらくは、async/awaitと同様に、古い.NET Frameworkを対象としたNuGetパッケージが提供されるものと思われます。
あれこれ書きましたが
まあ、さすがに最近、.NET Framework 2.0案件の話は聞くこと減って来たかなぁ…
Windows 7/Windows Server 2008 R2の標準インストールでのバージョンが.NET Framework 3.5.1なので、割かし、最低ラインがここ。また、Windows 8/Windows Server 2012の場合は.NET Framework 4.5。なので、3.5と4.5の場合だけ大まかに覚えておけばいいと思います。
- .NET Framework 3.5 = Windows 7 … async/awaitとdynamic以外は平気(Caller Infoだけ、やりよう次第)
- .NET Framework 4.5 = Windows 8 … 全部平気
ということで、今日書いた内容、実質的に「Windows Server 2003 R2をまだお使いの方、かつ、サーバー側開発なのになぜか.NET Frameworkのバージョンを2.0から上げれない方」を対象にした非常にニッチな話な気もしつつ。
一応、言語のバージョンとフレームワークのバージョンの関係性の説明ということで。
今から始める、Windows 10&新.NETへの移行戦略
第7回業開中心会議で登壇してきました。
変わらない
聞いてた方からの感想で「『変わらなくていい』なんですね(笑)」などというお言葉もいただきまして。
まあ、僕個人の意見は元々、「使いたくないやつが使う必要はない。」「LINQもvarも、使う・使わないとかで論争すること自体どうでもいい。」「でも、使いたいやつに使わせないような統制取るやつは滅びろ。」ですからね。もちろん、コードレビューなんかで「LINQ使うとこれだけシンプルになるよ」→「そっちの方がいいですね」ってような流れはあるけども、強制するものではないと思う(11ページで書いているように、privateな部分のコードはうるさく言ってもしょうがない。LINQやvarはそのprivateな部分の機能)。
選べる自由が大事。選ばせないやつは本気で滅びろ。
変えれない
開発者の声としてよく聞くのは「変えたいんですけどもなかなか大変で」ってやつです。みんなほんとは新しいもの使いたい。「あのフレームワークいいから早く滅びろ」とか呪いの言葉を吐きながら、5~10年前のアプリを保守してたりするじゃないですか。
変えたいけども変えれない理由は当然、コストで、じゃあそのコストをどうやって下げていこうってのが最近のトレンドかなぁと。
今日の講演、ishisakaさんに「なんか犠牲的アーキテクチャの話になっている感じ」なんて言われましたけど、まさにそれだと思うんですよね。僕が犠牲的アーキテクチャ(原文、和訳、InfoQ記事)の話を見た時に思ったのは、「.NET Coreはこれを支援できるアーキテクチャだ」でした。もちろんこれは、最近のソフトウェア開発トレンドに名前が付いただけの話で、マイクロソフト(のAzure/ASP.NETチーム)はちゃんとトレンドに乗れてるってだけの話ではあるんですが。新しい概念に名前が付くってのも大事で、その大事なタイミングで今回の登壇できたのは割とよかったのかなと思ったり。
補足記事(を書きたい)
今回の話、3点ほど補足記事を書きたいなぁと思っています。
1つ目: .NET 2.0でC# 6.0
1つ目は資料の10ページ目の内容「.NET 2.0でもC# 6.0使えます」。
まあ、実は今もう、GitHub上に、どのC#言語機能がどのバージョンの.NETで動くかに関するサンプルコードがあったりするんですけども(6.0のサンプルが未完。もうちょっとで完成)。これをベースにした話。
2つ目: NuGetパッケージとプロジェクトの区別がなくなる
2つ目は24ページ目の内容「区別がなくなることで」。
この開発フローの具体的な、プロジェクトからNuGetパッケージを作ったり、NuGet参照していたものをプロジェクト参照に差し替えたりの話。
3つ目: Xamarin Studio
3つ目は42ページ目の内容「補足: Xamarin Studio」。
これ、外注先の会社さんが、うちの作ったフレームワーク乗ることになったはいいけども、そちらの開発環境がMacしかなく、仮想マシン立てるとかWindows機買ってもらうよりも前に、まずXamarin Studioでのビルドを試みてみたという実話。半日くらいは試行錯誤があったんですけども、最終的には何の問題もなく、Mac上でビルド通ったそうです。その、半日程度の試行錯誤の話。
.NET for every developers, every devices
Connect(); Microsoft Visual Studio vNext & Azureっていうイベントをオンライン配信しているわけですが。.NET界隈的にはかなり久々なレベルのでかい発表がありました。
MSDNブログでも、各チームがいろんな記事を公開。
- Somasegar’s: Opening up Visual Studio and .NET to Every Developer, Any Application: .NET Server Core open source and cross platform, Visual Studio Community 2013 and preview of Visual Studio 2015 and .NET 2015
- ScottGu: Announcing Open Source of .NET Core Framework, .NET Core Distribution for Linux/OSX, and Free Visual Studio Community Edition
- .NET: Announcing .NET 2015 Preview: A New Era for .NET
- .NET: .NET Core is Open Source
- Visual Studio ALM: Introducing Visual Studio’s Emulator for Android
- Azure: Announcing Azure SDK 2.5 for .NET and Visual Studio 2015 Preview
テーマ的には、every developers, every devices。
無料版Visual Studio
今までも、Visual StudioにはExpressエディションっていう無料版があったわけですが、
- デスクトップ開発用、Web開発用、…というように、ターゲットごとに分かれてた
- 拡張機能を入れれなかった
などの制限があって、ご時世的につらいものがありました。何がつらいって、
- Devices and Services (Web + 携帯端末)なご時世にターゲットを分けられても困る
- XamarinやUnityゲーム エンジンなどの勢いがあるご時世に、拡張を入れれないとか困る
という感じ。
なので、このたび出た新しいエディションが、Communityエディション。
上記のようなターゲット分割・拡張面での制限がなくなった版(有償エディションでいうとProfessional相当の機能っぽい)。使える条件は以下の通り。
- PC 250台以下・年商100万ドル以下(non-enterprise)の会社で、5ユーザー分まで
- 非商用利用、教育、研究、オープンソースへの貢献で無制限
同時に、Xamarin との提携で、Xamarin StarterでもVisual Studio拡張が使えるようになったらしくて、それと組み合わせれば、上記条件下だとVisual Studioを使ったAndroid/iOS開発も無償でできるみたいです。
.NETのオープンソース化
今までも、だいぶオープン化していたわけですが
- .NET Compiler Platform (C# & VB)
- F#
- ASP.NET
- Entity Framework
ついに.NET自体もオープンソースになりました。
-
- http://referencesource.microsoft.com/ で公開されていたものがGitHubホスティングになって、MITライセンスに
-
- .NET Core (今で言うストア アプリ向け.NET、今後のASP.NET vNext/.NET Native)のクラス ライブラリのリポジトリ
まだ、オープンになっている部分はそんなに多くないんですが、.NET Coreのランタイム自体のオープンかも含めて、これから随時足していく(作業中)だそうです。Windows以外のプラットフォーム(MacとかLinux)でのビルド・実行に関しても作業中。
.NET Coreなので、要は、Win32 API依存なところは一切なしな部分。プレス リリースなんかでは、「.NETのserver stackをオープン化」とか説明されています。要は、Azure方面が頑張った結果のオープン化。
.NET Core上で使えるクラス ライブラリは、現状のストア アプリ向け.NETがベースのはず。で、.NET Nativeもこの.NET Coreがベース(なので、server stackとは言いつつ、クライアント向けも今後はこの.NET Coreを基礎として作られるはず)。
.NET 2015
最近もう、「一斉にバージョン5としてリリースします!」みたいな時代じゃなくて、バージョン番号がパーツごとにばらばらになっています。
-
.NET
- .NET Framework 4.6: 現状のデスクトップ.NETの新バージョン
- .NET Core 5: ASP.NET vNext (cloud-optimizedモード)とか.NET Nativeが使ってるモジュラー性を高めたバージョンの.NET
-
.NET Compiler Platform (旧codename “Roslyn”): できたてほやほや。当然バージョン1
- C# 6.0
- VB 14
- RyuJIT: 新しいJITコンパイラー
- ASP.NET 4.6
- Visual Studio 2015
この辺りを総称して、「.NET 2015」と呼んでいくみたい。
Every developers, every devices
要するに、誰でも、何の上で動くアプリでも、すべての人に.NETを。