本サイトからスピンオフした姉妹サイトです。C#2016年2月9日メソッドが複数の値を戻す場合など、複数のデータを緩くまとめて、扱いたい場合はよくある。C#の次バージョンではこれを簡潔に記述するための機構として「タプル型」が導入される。現在、C#への機能追加に当たって、いくつかのテーマが設けられている。その中でも大きなものの1つが「データ処理」である。3.0でLINQと関連して多くの言語機能が取り入れられたが、まだまだ検討すべきことは多く残されている。今回は、そんなデータ関連の提案の1つであるタプル型について紹介していこう。...」などを一般化したN-tupleという言葉に由来する。単純に「複数のもの」という意味の言葉だ。「データを複数束ねたもの」程度の意味であり、「タプル型」はかなり「緩い」型を意味する。7で提案されているものは図1に示すようなものである*1。7のタプル型はC#言語の機能として追加されるという違いがある。多値戻り値タプルの一番の用途は、複数の値を戻り値として返すメソッドである。数値列を与えて、その和と個数を同時に計算して返すメソッドTallyを考えてみよう。現状のC#でもいくつかの手段がある。専用の型を作るTupleクラス(System名前空間)のような汎用の型を使う1つ目はout引数を利用するもので、コードはリスト1に示すようになる。out引数を使ったTallyメソッド確かにこれで複数の戻り値を返せるが、out引数は使い勝手が悪く、できれば避けたい。致命的なのは、非同期メソッドで使えないことである。Tallyメソッドの中にawait演算を必要とするような処理が挟まっていた場合、リスト2のようには書けない。out引数の問題(非同期メソッドで利用不可)。このコードはコンパイルできない2つ目は、リスト3に示すように、専用の型を作って返す方法である。専用の型を使ったTallyメソッドの実装この方法の問題は、このためだけに型を作るのが適切かどうか、過剰ではないかという問題である。この戻り値の型は、TallyResult(=Tallyメソッドの結果)としか言いようがない。他に候補を挙げるなら、SumAndCount(=sumとcountを持つ何か)など、メンバーを見れば分かるような意味のない名前になるだろう。強い型付けの良さは「意味の分かる名前を付けられる」ことであって、「意味のないものにまで名前を付ける」ことではない。型名に意味がないのなら、リスト4に示すように、Tupleクラスのような汎用の型で置き換えるという方法を取ることもできる。汎用的な型を使ったTally実装ただし、このコードは実際にはコンパイルできない。Tuple型のメンバーItem1とItem2は書き換え不能である。このコードはあくまで概念の説明用。この場合は逆に、sum、countといった意味のある名前まで消えてしまう。リスト3で戻り値の型名に意味がないといったのは、あくまでも「メンバー名を見れば分かるから冗長」という話である。メンバー名まで消えるのではさすがに情報が少なすぎる。Item1とItem2のどちらが和で、どちらが個数かわからなくなるようでは実用に耐えないだろう。7でタプル型が提案されている。タプル型を使うとリスト5のような書き方ができる。count)というような書き方がタプル型である。7で導入予定のタプル型を使ったTallyメソッドの実装すなわち、タプル型は、メンバー名だけで十分にその型の性質を表せ、型自体の名前は不要な場合に使える型である。最初にout引数で説明したような非同期処理における問題も、タプル型であれば解消できる。リスト6に示すようなコードが書ける。引数とタプル型メソッドの引数と戻り値は、入力と出力であり、表裏の関係にある。戻り値として返したものは、そのまま別のメソッドの引数に与えられることがある。先ほどの例でいうと、Tallyメソッドが「和と個数を返す」ものなのに対して、「和と個数を受け取る」メソッドが考えられる。リスト7に示すような平均値の計算が分かりやすい例だろう。※後述のリスト8~11でこのメソッドを使用する。7のタプル型は多値戻り値を最大の目的として導入されたものであるため、表裏の関係にある引数との類似が多く見られる。なったものではなく、設計思想として、タプル型は引数と似せてある。リスト8やリスト9に示すように、メソッドへの引数の受け渡しと同じ構文でタプルを構築する。引数の受け渡しに位置指定渡し(リスト8)と名前指定渡し(リスト9)があるのと同様、タプルも位置指定と名前指定ができる。名前付きタプル構築と名前指定引数。この場合はxに対して型推論が利くまた、リスト10に示すように、引数への分解(splatting)も自動的に行われる。リスト11に示すように、タプル型の戻り値を別のメソッドに直接渡すこともできる。タプル型の戻り値を別のメソッドに直接渡すTallyメソッドはリスト5、Averageメソッドはリスト7で定義したもの。3.0)とタプル型C#には、3.0のころから匿名型(=匿名クラス)というタプル型とよく似た機能が提供されている。現状の匿名型にはいくつかの問題があり、タプル型ではそれを解消しようとしている。匿名型自体にも手を入れて、現状の問題を解消できないか検討中である。結果的に、匿名型とタプル型はより一層似た機能になるが、その違いについても触れておこう。3.0の匿名型を知っている人なら、タプル型を戻り値に使えることにまず驚くかもしれない。タプル型は、言語機能的に匿名型に近いものである。匿名型は、フィールドやメソッドの引数、戻り値には使えない。12のようなコードから、コンパイル時に(少なくとも今の実装では)リスト13のようなクラスを生成する機能である。匿名型からコンパイラーによって生成されるクラス実際にはGetHashCodeなどのメソッドも生成される。名前は通常のC#ではあり得ない記号交じりのものになる。}という書き方で得られる匿名型であっても、アセンブリごとに異なるクラスが生成され、それらの間の変換はできない点である。その結果、匿名型はアセンブリの間をまたげず、フィールドやメソッド引数、戻り値に使えなくなっている。この問題はタプル型では解消する予定である。タプル型の実装タプル型の具体的な実装方法だが、今のところ、リスト14に示すような、汎用の型ValueTuple構造体への展開になりそうだ。先ほど説明した通り、現在の匿名型のような「クラスの生成方式」ではアセンブリをまたげないという問題がある。この問題を解消するための案はいくつかあり、それぞれに一長一短があるが、現状ではリスト14の方式が最有力である。汎用のValueTuple構造体に展開した上で、メンバー名は属性として残すという方式である。ここで、ValueTuple構造体はリスト15のような実装となっている。実際にはGetHashCodeやEqualsなどのメソッドも持っている。フィールドがreadonlyになるかどうかもまだ変更の可能性がある。用途を絞らない場合、実測に基づく結論として、タプル型のようなものは参照型(つまりクラス)の方がよいとされている。7で提案されているタプル型は、メソッドの戻り値として使い、すぐにメンバーを分解してそれぞれ別変数で受け取るというような用途が想定されていて、この用途に絞る場合には値型(つまり構造体)の方が有利だろうと判断されている。4以降)すでにあるTupleクラス(System名前空間)ではなく、新たにValueTuple構造体を導入することになった。前節で説明したような、汎用の型+属性で名前を残すという実装方法は、匿名型に対しても応用できるだろう。そこで、匿名型に対してもリスト16のような書き方を許そうという提案も出ている。型を明示的に書け、アセンブリをまたげる匿名型この方法であれば、タプル型と同様に、匿名型も型名を明示できるし(denotable)、アセンブリをまたぐこともできる。匿名型とタプル型の差タプル型も匿名型への改善も提案が通ったとすると、これらは非常に似たものとなる。マッチングの回で説明する。匿名型はオブジェクト初期化子(プロパティ)、タプル型はコンストラクター(引数)というように、何の類推になっているかという差がある。これは単に書き方の問題である。機能的には参照型か値型かという差になるだろう。この参照型か値型かという差だけのために、こんな似て非なる構文を導入するかどうかという問題もある。匿名型の改善には、既存の匿名型を使っているコードを壊さずに修正できるかどうかという課題も待っている。その結果、匿名型の改善は優先度が低めになっている。まとめ主に多値戻り値を返すための型として、タプル型が提案されている。y)というような書き方で、複数のデータをまとめた型を作る機能である。多値戻り値という用途上、その表裏の関係にあるメソッド引数とよく似た書き方になっている。タプル型には、アセンブリをどうやってまたぐかや、今ある類似の機能である匿名型との兼ね合いなど、いくつかの課題もある。この既知の課題さえクリアできれば、非常に便利な機能であることは間違いない。非同期メソッドと多値戻り値の相性の悪さが改善するし、無意味な型を増やす必要がなくなる。型名をなくす緩さを嫌う人もいるだろうが、強い型付けの良さは「意味の分かる名前を付けられる」ことであって、「意味のないものにまで名前を付ける」ことではない。1.0がプレビュー版だった頃からC#によるプログラミング入門を公開していて、C#とともに今年で15年になる。最近の自己紹介は「C#でググれ」。※以下では、本稿の前後を合わせて5回分(第1回~第5回)のみ表示しています。INDEX]を参照してください。日本を代表する「C#(でぐぐれ)」の人、岩永信之氏によるコラムが遂に登場。今回はオープンソースで開発が行われているC#と開発者の関わり方について。7」についての議論が進んでいる。その中で提案されている「式」に関する新機能を取り上げる。複数データをまとめるための言語機能、タプル型メソッドが複数の値を戻す場合など、複数のデータを緩くまとめて、扱いたい場合はよくある。C#の次バージョンではこれを簡潔に記述するための機構として「タプル型」が導入される。型に応じた分岐や型の分解機能、パターンマッチングオブジェクトの型を階層的に調べて分岐処理を行いたい場合がある。そのための機能として、C#の次バージョンでは「パターンマッチング」が追加される。パターンマッチングの内部的な仕組みC#の次バージョンに追加される「パターンマッチング」の挙動(パターンマッチングがどう展開されるのかや、その実現方法)について説明する。機械学習エンジニアを目指す人~初中級者のための技術情報サイトです。「機械学習&AI」「クラウド&ビッグデータ」「IoTデバイス」のネット記事情報を共有中。開発者のためのSlackチーム、作りました:「機械学習&AI」「クラウド&ビッグデータ」「IoTデバイス」のネット記事情報を共有中。2020最適なビューへの切り替えを推奨します:スマートフォン用表示に。