詳説! Visual Basic 10, C# 4.0 の新機能 ~Visual Studio 2010 で進化したコーディング環境~ セッション ID:T6-309 詳説! Visual Basic 10, C# 4.0 の新機能 ~Visual Studio 2010 で進化したコーディング環境~ マイクロソフト株式会社 デベロッパー&プラットフォーム統括本部 エバンジェリスト 新村 剛史
セッションの目的とゴール Session Objectives and Takeaways Visual Basic 10、C# 4.0 の新機能を 理解していただく。 Visual Studio 2010 のコーディング機能を 理解していただく。 セッションのゴール Visual Studio 2010 で Visual Basic 10、 C# 4.0 の新機能を活用した開発が可能になる。
アジェンダ 開発言語の今とこれまで 開発言語の新機能 Visual Studio 2010 エディター新機能 まとめ 歴史と流れ C# Visual Basic 共通項目 Visual Studio 2010 エディター新機能 コードを読む コードを書く / 編集する デバッグする まとめ
開発言語の今とこれまで 開発言語の歴史
開発言語の歴史 1950 1960 1970 1980 1990 2000 2010 VB.NET Visual Basic MSBasic Fortran C Java ALGOL Ruby F# Small talk Python Lisp PHP COBOL Perl
C# と Visual Basic の歩み寄り NOW! C# 4.0 VB 10 2010 C# 3.0 VB 9 LINQ C# 2.0 ジェネリクス C# 1.0 VB 7 .NET への対応 2002 VB4-VB6 コンポーネント対応 VB1-VB3 Windows 開発の簡素化
開発言語の新機能 C# Visual Basic 共通項目
C# と VB の新機能比較 C# VB オプション引数・名前付き引数 遅延バインド 簡易な COM 相互運用 自動実装プロパティ コレクション初期化子 複数行のラムダ式 動的言語のサポート 共変性と反変性 コード コントラクト 既存機能 一部既存機能 新機能
C# C# の新機能 C# VB オプション引数・名前付き引数 遅延バインド 簡易な COM 相互運用 自動実装プロパティ コレクション初期化子 複数行のラムダ式 動的言語のサポート 共変性と反変性 コード コントラクト 既存機能 一部既存機能 新機能
C# オプション引数・名前付き引数 呼び出し時に 引数を省略可能 順序入れ替え可能 // メソッドの宣言 void Method1(string a, string b = "b", string c = "c") // メソッドの呼び出し Method1("a", "d", "e"); // 通常呼出し Method1("a"); // 引数省略 Method1("a", c: "e"); // 名前指定呼び出し Method1("a", c: "e", b: "d"); // 順序変更
C# 実装の仕組み コンパイラの機能として実現 呼び出し側は常に展開される void Method1(string a, string b = "b", string c = "c") void Method1( string a, [Optional, DefaultParameterValue("b")] string b, [Optional, DefaultParameterValue("c")] string c) Method1("a"); Method1("a", "b", "c");
C# オプション引数のルール 通常系 コンパイルエラー 可変個のパラメーター オプション引数は普通の引数より後ろ オプション引数の後ろに追加可能 void Method1(string a, string b = "b", string c = "c") void Method1(string a, string b = "b", string c) void Method1(string a, string b = "b", params string[] c)
C# メソッド呼び出しの解決順序 こんな呼び出しをした場合 解決順序 1 2 3 Method1("a"); void Method1(string a){} void Method1(string a, string b = "b"){} void Method1(string a, params string[] b){}
C# 遅延バインディング DLR dynamic キーワード obj DLR を経由して実行時に型確定、実行 コンパイル dynamic obj = ObjectFactory.GetSomeObject(); obj.Method(); コンパイル 静的型チェックをバイパス インスタンス生成 DLR Binder obj メソッド実行 Object 型 として機能 注:Visual Basic の遅延バインディングも DLR を経由 する方式に変更されている
C# dynamic 型への操作による型変換 dynamic 型 固有型 dynamic 型に対する操作 固有型への代入
ダックタイピング C# 遅延バインディングの利用例 型としては異なっていても同様の機能を利用 アセンブリ A (Ver. 1.0) Class A Method1() Method2() A.Method1(); A.Method2(); アセンブリ A (Ver. 2.0) Class A Method1() Method2() Method3() ダックタイピング
リフレクションの嵐 Type.Missing の嵐 C# COM 相互運用 (Before) 遅延バインディング 煩雑な引数 Type type = Type.GetTypeFromProgID("Excel.Application"); object excelApp = Activator.CreateInstance(type); object workBooks = excelApp.GetType().InvokeMember("Workbooks", BindingFlags.GetProperty, null, excelApp, null); workBooks.GetType().InvokeMember("Add", BindingFlags.InvokeMethod, null, workBooks, null); excelApp.GetType().InvokeMember("Visible", BindingFlags.SetProperty, null, excelApp, new object[] {true}); リフレクションの嵐 excelApp.get_Range("A1", "B4").AutoFormat(myFormat, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing); Type.Missing の嵐
C# COM 相互運用 (After) 遅延バインディング (dynamic) オプション引数 dynamic excelApp = new Application(); excelApp.Workbooks.Add(); excelApp.Visible = true; excelApp.Range["A1", "B4"].AutoFormat(Format: myFormat);
VB VB の新機能 C# VB オプション引数・名前付き引数 遅延バインド 簡易な COM 相互運用 自動実装プロパティ コレクション初期化子 複数行のラムダ式 動的言語のサポート 共変性と反変性 コード コントラクト 既存機能 一部既存機能 新機能
VB 自動実装プロパティ バッキング フィールド ウォッチ式、デバッグ ツール、クラス内で 使用可能 IntelliSense では非表示 Public Property Name As String 暗黙的に生成 Private _Name As String バッキング フィールド ウォッチ式、デバッグ ツール、クラス内で 使用可能 IntelliSense では非表示 自動実装プロパティの展開 空白行:”G” + [Enter] or “S” + [Enter]
VB コレクション初期化子 From キーワード 内部的には Add メソッドが呼ばれる Dim items As New List(Of String) From {"Foo", "Bar"} Dim items As New List(Of String) items.Add("Foo") items.Add("Bar")
VB オブジェクト初期化子との組合せ 要素にオブジェクト初期化子を利用 コレクション自体の初期化では組合せ不可 Public Items As New List(Of Sample1) From { New Sample1 With {.Foo = "Foo", .Bar = "Bar"}, New Sample1 With {.Foo = "Foo1", .Bar = "Bar1"}} Dim days = New List(Of String) With {.Capacity = 7} From {"Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"}
VB 暗黙の行連結 “_” なしの改行が可能 ただし、どこでも良いわけではない Sub Go( ByVal x As Integer, ByVal y As Integer, ByVal z As Integer ) Dim query = From n In {123, 456, 789} Order By n Select n + x End Sub 改行可能な条件は Appendix をご確認ください。
VB 複数行のラムダ式とサブルーチン 複数行のラムダ式 ラムダ式によるサブルーチン 複雑なラムダ式の記述が可能に ' 単一行 Dim increment1 = Function(x) x + 1 ' 複数行 Dim increment2 = Function(x) Return x + 2 End Function Dim writeline1 = Sub(x) Console.WriteLine(x) Dim writeline2 = Sub(x) Console.WriteLine(x) End Sub
VB ラムダ式における戻り値の型解決 Dim typeDef1 = Function(x) x + 1 '型推論 Dim typeDef2 = Function(x) As Long '型指定 Return x + 1 End Function Dim typeDef3 = Function(x) If (x >= 0) Then Return Integer.Parse(x) Else Return Double.Parse(x) End If '全ての型に拡大変換可能な型に型推論 この例は Double
[参考]ラムダ式とは 式とステートメントを含めることができる匿名関数 デリゲート型 式ツリー型 デリゲートの匿名メソッドを簡易な表記で実現 式を木構造で表す。コンパイラはコードを出力。 実行時にコンパイル。(LINQ の遅延実行) .NET Framework 4 から割り当て式、 制御フロー式を扱う API が追加に。
[参考]式ツリー .NET Framework 3.5 まで .NET Framework 4 から Function(x) x + 1 For i = 1 To 10 x += i Next Return x End Function For Return = <= {} x i 1 i 10 += x i 注:上記式ツリーはイメージです。実際に生成されるツリーとは異なります。
C#/VB C# と VB の新機能 C# VB オプション引数・名前付き引数 遅延バインド 簡易な COM 相互運用 自動実装プロパティ コレクション初期化子 複数行のラムダ式 動的言語のサポート 共変性と反変性 コード コントラクト 既存機能 一部既存機能 新機能
Dynamic Language Runtime C#/VB 動的言語のサポート (DLR) IronPython IronRuby C# VB.NET Others … Dynamic Language Runtime 式ツリー 動的オブジェクトの相互運用性 呼び出し元 のキャッシュ Object Binder JavaScript Binder Python Binder Ruby Binder COM Binder
Dynamic Language Runtime DLR の仕組み 式ツリーによって構文を抽象化 コンパイルされた式ツリーはCallSiteにキャッシュされる Dynamic Language Runtime 動的オブジェクトの相互運用性 Function A For Return = i 1 <= 10 {} x += コンパイル CLR 呼び出し元 のキャッシュ 式ツリー
C#/VB 共変性と反変性 インターフェイスにおける型システムの 柔軟性を実現 汎用デリゲート ジェネリック インターフェイス 派生 基底 戻り値の型 反変性 引数の型 派生 基底 実体
C# 共変性と反変性 (デリゲート) C# 2.0 で実現されていました delegate object BaseMethod(string x); // 共変性 public static string Method1(string x) { return x; } BaseMethod baseMethod1 = Method1; //反変性 public static object Method2(object x) { return x.ToString(); BaseMethod baseMethod2 = Method2; C# 2.0 で実現されていました
VB 共変性と反変性 (デリゲート) Delegate Function BaseMethod(ByVal x As String) As Object '共変性 Public Shared Function DeliMeth1(ByVal x As String) As String Return x End Function Dim baseMethod1 As BaseMethod = AddressOf DeliMeth1 '反変性 Public Shared Function DeliMeth2(ByVal x As Object) As Object Dim baseMethod2 As BaseMethod = AddressOf DeliMeth2
共変性と反変性 (ジェネリック インターフェイス) C#/VB 共変性と反変性 (ジェネリック インターフェイス) 共変性:out キーワード 反変性:in キーワード C# // 共変性の定義の例 public interface IEnumerable<out T> : IEnumerable // 反変性の定義の例 public interface IComparable<in T> VB ‘ 共変性の定義の例 Public Interface IEnumerable(Of Out T) Inherits IEnumerable ‘ 反変性の定義の例 Public Interface IComparable(Of In T)
C# 共変性と反変性 (ジェネリック) // 共変性 IEnumerable<String> strings = new List<String>(); IEnumerable<Object> objects = strings; // 反変性 IComparable<string> strCompare = new ObjCompare(); class ObjCompare : IComparable<object> { public int CompareTo(object other){…} } strCompare.CompareTo("TechEd Japan");
VB 共変性と反変性 (ジェネリック) ‘ 共変性 Dim strings As IEnumerable(Of String) = New List(Of String) Dim objects As IEnumerable(Of Object) = strings ‘ 反変性 Dim strCompare As IComparable(Of String) = New ObjCompar() Class ObjCompar Implements IComparable(Of Object) Public Function CompareTo(ByVal other As Object) As Integer ・・・・ End Function End Class strCompare.CompareTo("TechEd Japan")
C#/VB Code Contract 契約による設計 (Design by Contract) バートランド メイヤー 契約によりオブジェクトのインターフェイスを厳密に定義しコードに記述 コードが必要とする条件 (事前条件) コードが保証する内容 (事後条件) 常に満たされるべき条件 (不変表明) 注:デフォルトの状態ではほとんどの Contract ステートメントは IL には情報として含まれません。
C#/VB 事前条件 メソッド開始前の状態をチェック VB public string Method1(string name){ Contract.Requires(!String.IsNullOrEmpty(name)); Contract.Requires<ArgumentException> (name.Length < 128, "Too long string"); こちらは IL に組み込まれる VB Public Function Method1(ByVal name As String) As String Contract.Requires(Not String.IsNullOrEmpty(name)) Contract.Requires(Of ArgumentException) (name.Length < 128, "Too long string") こちらは IL に組み込まれる
C#/VB 事前条件 (移行) 既存の引数チェックを Contract 化 VB public void Method2(string name){ if (String.IsNullOrEmpty(name)) throw new ArgumentException(); Contract.EndContractBlock(); VB Public Sub Meshotd2(ByVal name As String) If (String.IsNullOrEmpty(name)) Then Throw New ArgumentException() End If Contract.EndContractBlock() Contract 化しても既存のコードは IL 上にも反映されます。
C#/VB 事後条件 メソッド実行後の状態をチェック 正常終了時:Ensures 例外終了時:EnsuresOnThrow VB Contract.Ensures(Contract.OldValue<int> (this.list.Count) == this.list.Count -1); Contract.EnsuresOnThrow<Exception> (this.list.Count != 0); VB Contract.Ensures( Contract.OldValue(Of Int32)(Me.list.Count) = Me.list.Count - 1) Contract.EnsuresOnThrow(Of Exception)( Me.list.Count <> 0)
C#/VB 不変条件 全てのクラスに対する処理時に状態をチェック VB [ContractInvariantMethod] protected void InvaliantMethod() { Contract.Invariant(list != null); } VB <ContractInvariantMethod()> Protected Sub InvaliantMethod() Contract.Invariant(Me.greetings IsNot Nothing) End Sub
ツールによる検証、実行時検証 ツールによる解析、実行時検証 (アドオン) 実行時検証 静的検証 http://msdn.microsoft.com/en-us/devlabs/dd491992.aspx
[参考] Contract の記述順序のルール If-then-throw statements 下位互換性のあるパブリックな事前条件。 Requires すべてのパブリックな事前条件。 Ensures すべてのパブリックな (標準の) 事後条件。 EnsuresOnThrow すべてのパブリックな例外の事後条件。 すべてのプライベートな/内部の (標準の) 事後条件。 すべてのプライベートな/内部の例外の事後条件。 EndContractBlock if-then-throw の事前条件を他のコントラクトなしで 使用する場合は、EndContractBlock を呼び出して、 前の if チェックがすべて事前条件であることを 示します。
Visual Studio 2010 エディター新機能 コードを読む コードを書く / 編集する デバッグする
強化された検索機能 マッチング キーワード一致 キャメル表記の頭文字
[Ctrl]+[Shift]+[↑/↓] 参照の強調表示 ドキュメント内のシンボルのインスタンスを強調表示 VB では加えて If...Then...Else ステートメント Select...Case ステートメント Do...Loop ステートメント For...Next ステートメント For Each...Next ステートメント Try...Catch...Finally ステートメント Class ステートメント Function ステートメント Sub ステートメント Property ステートメント Using ステートメント With...End With ステートメント [Ctrl]+[Shift]+[↑/↓]
呼び出し階層 メソッドの「呼び出し先」と「呼び出し元」を追跡
コード生成 NEW NEW NEW 型の生成 「XXX のクラスを生成する」 →同名のファイルを生成 「新しい型の生成」 →ダイアログによる詳細設定 型 メソッド C# VB NEW VS2005 から提供 NEW NEW
[Ctrl] +[Alt]+[Space] IntelliSense の強化 検索機能 コード検索機能のマッチング ルールを採用 候補提示モード 入力候補モード 候補提示モード [Ctrl] +[Alt]+[Space]
ヒントチップ 追跡したい値をコードの近くにピン留め コメントの追記も可能
ブレークポイントの管理が可能に ラベル付による分類とフィルタリング インポートとエクスポート XML 形式でファイルに保存
まとめ
まとめ Visual Basic と C# のどちらでも同じように強力な開発ができます。 得意な言語で便利な開発を可能にする VB オプション引数・名前付き引数 遅延バインド 簡易な COM 相互運用 自動実装プロパティ コレクション初期化子 複数行のラムダ式 動的言語のサポート 共変性と反変性 コード コントラクト 得意な言語で便利な開発を可能にする を是非、ご活用ください。
関連セッション T6-302:Day2 9:20-10:30 Room B Visual Studio 2010 の 新しいテスト機能による ソフトウェア品質の向上 T6-501:Day3 15:20-16:30 Room D 多言語パラダイムによる実装手法 ~ 動的言語、関数型言語などを含めた プログラミング言語の有効活用へ ~ T6-308:Day1 15:20-16:30 Room E .NET Framework 4 を使用した 並列プログラミングと デバッグ、プロファイリング H-317:Day2, Day3 Visual Studio 2010 ~ Test Manager による新しいテスト機能の活用 ~ BOF-06: Let's Dynamic : IronRuby で探す .NET の付加価値
リファレンス .NET Framework デベロッパー センター http://msdn.microsoft.com/ja-jp/netframework/default.aspx Visual Studio デベロッパー センター http://msdn.microsoft.com/ja-jp/vstudio/default.aspx .NET 開発コード サンプル集 Code Recipe http://msdn.microsoft.com/ja-jp/samplecode.recipe.aspx Days with Microsoft Web Platform (Blog) http://blogs.msdn.com/tashinmu/
ご清聴ありがとうございました。 T6-309 アンケートにご協力ください。
Appendix
VB10 暗黙の改行の条件 (1/3) 構文要素 例 コンマ (,) の後。 Public Function GetUsername(ByVal username As String, ByVal delimiter As Char, ByVal position As Integer) As String Return username.Split(delimiter)(position) End Function 左かっこ (() の後、または右かっこ ()) の前。 Dim username = GetUsername( Security.Principal.WindowsIdentity.GetCurrent().Name, CChar("\"), 1 ) 左中かっこ ({) の後、または右中かっこ (}) の前。 Dim customer = New Customer With { .Name = "Terry Adams", .Company = "Adventure Works", .Email = "terry@www.adventure-works.com" } XML リテラル内の埋め込み式の開始記号 (<%=) の後、または埋め込み式の終了記号 (%>) の前。 Dim customerXml = <Customer> <Name> <%= customer.Name %> </Name> <Email> customer.Email </Email> </Customer> 連結演算子 (&) の後。 cmd.CommandText = "SELECT * FROM Titles JOIN Publishers " & "ON Publishers.PubId = Titles.PubID " & "WHERE Publishers.State = 'CA'"
VB10 暗黙の改行の条件 (2/3) 構文要素 例 Dim fileStream = 代入演算子 (=、&=、:=、+=、-=、*=、/=、\=、^=、<<=、>>=) の後。 Dim fileStream = My.Computer.FileSystem. OpenTextFileReader(filePath) 式内の二項演算子 (+、-、/、*、Mod、<>、<、>、<=、>=、^、>>、<<、And、AndAlso、Or、OrElse、Like、Xor) の後。 Dim memoryInUse = My.Computer.Info.TotalPhysicalMemory + My.Computer.Info.TotalVirtualMemory - My.Computer.Info.AvailablePhysicalMemory - My.Computer.Info.AvailableVirtualMemory Is 演算子および IsNot 演算子の後。 If TypeOf inStream Is IO.FileStream AndAlso inStream IsNot Nothing Then ReadFile(inStream) End If メンバーの修飾子文字 (.) の後、メンバー名の前。ただし、With ステートメントを使用する場合や型の初期化リストの値を指定する場合は、メンバーの修飾子文字の後に行連結文字 (_) を含める必要があります。With ステートメントやオブジェクト初期化リストを使用する場合は、代入演算子 (= など) の後で改行することをお勧めします。 Dim query = From n In {123, 456, 789} Order By n Select n + x Dim aType = New With {.PropertyName = "Value"} Dim log As New EventLog() With log .Source = "Application" End With
VB10 暗黙の改行の条件 (3/3) 構文要素 例 XML 軸プロパティ修飾子 (.、.@、...) の後。ただし、With キーワードを使用する場合は、メンバーの修飾子を指定する際に行連結文字 (_) を含める必要があります。 Dim customerName = customerXml. <Name>.Value Dim customerEmail = customerXml... <Email>.Value 属性を指定する際の小なり記号 (<) の後、または大なり記号 (>) の前。また、属性を指定する際の大なり記号 (>) の後。ただし、アセンブリ レベルまたはモジュール レベルの属性を指定する場合は、行連結文字 (_) を含める必要があります。 < Serializable() > Public Class Customer Public Property Name As String Public Property Company As String Public Property Email As String End Class クエリ演算子 (Aggregate、Distinct、From、Group By、Group Join、Join、Let、Order By、Select、Skip、Skip While、Take、Take While、Where、In、Into、On、Ascending、および Descending) の前後。複数のキーワードで構成されるクエリ演算子 (Order By、Group Join、Take While、および Skip While) のキーワード間で改行することはできません。 Dim vsProcesses = From proc In Process.GetProcesses Where proc.MainWindowTitle.Contains(“Hello!") Select proc.ProcessName, proc.Id, proc.MainWindowTitle For Each ステートメントの In キーワードの後。 For Each p In vsProcesses Console.WriteLine("{0}" & vbTab & "{1}" & vbTab & "{2}", p.ProcessName, p.Id, p.MainWindowTitle) Next コレクション初期化子の From キーワードの後。 Dim days = New List(Of String) From { "Mo", "Tu", "We", "Th", "F", "Sa", "Su" }
共変性、反変性を提供する ジェネリック インターフェイスとデリゲート 型 共変の型パラメーター 反変の型パラメーター Action<(Of <(T>)>) ~ Action<(Of <(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>)>) ○ Comparison<(Of <(T>)>) Converter<(Of <(TInput, TOutput>)>) Func<(Of <(TResult>)>) Func<(Of <(T, TResult>)>) ~ Func<(Of <(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, TResult>)>) IComparable<(Of <(T>)>) Predicate<(Of <(T>)>) IComparer<(Of <(T>)>) IEnumerable<(Of <(T>)>) IEnumerator<(Of <(T>)>) IEqualityComparer<(Of <(T>)>) IGrouping<(Of <(TKey, TElement>)>) IOrderedEnumerable<(Of <(TElement>)>) IOrderedQueryable<(Of <(T>)>) IQueryable<(Of <(T>)>)