Catharsisようこそ。睡眠不足なプログラマのチラ裏です。この広告は、90日以上更新していないブログに表示しています。型プロバイダー(TypeProvider)のちょっとしたアレコレというのを書きました。書いたのはそーとー前ですが、今でも割と役に立つかもしれない以下の話題について扱っているので、気になるものがあればどうぞ。この記事は、TypeProviderに関する役立つものから役立たないものまで雑多な小ネタをいくつか適当に書いていきます。何かひとつでも引っかかるものがあって、持ち帰ってもらえれたら幸いかなと思います。Templateとゆーありがたいテンプレートが用意されていました!が、もう過去のもの。PaketなりNuGetなり、お好きな方法でインストールしましょう。こちらが現在メジャーなテンプレとなります。最新バージョンは現時点では1.1.3.88です。いう名前から察するにあえてやり過ぎないように意識しているのかもしれません。StarterPackだけでは満たされないF#er諸兄は、お好みでHelper関数などを別途作ります。typeof<T>.AssemblyTypeProviderでは、自身のAssemblyを取得する必要があるので適当に生やすとか。お作法的には、TypeProviderConfig.RuntimeAssemblyから取得する方がよいのかなあ?まあたぶんお好みで大丈夫かと。config.RuntimeAssembly)TypeProviderを作るためのシンプルなヘルパーをいくつか準備しておくのもいいでしょう。tyちなみにこちらは某サンプルにあるやつとほぼ同じやーつで。面白みは特にないです。TypeProviderのデバッグ方法TypeProviderのデバッグ方法については、いろいろな人が何度か取り上げている気がしますが。プロジェクトファイルfsprojに以下のような定義を追加し(VisualStudio上から設定可)、デバッグ時に別のVisualSudioが立ち上がるように設定してあげます。Studio氏が空気を読まずにDLLを掴みっぱなしにしてしまい、ビルドができなくなってしまいます。ファイルを開かないように気を付ければソリューション自体を分けなくともTypeProviderのデバッグ実行は可能ですが、デバッグ用プロジェクトのソリューションは分けておいた方が、なにかと捗るかなと思います。́・_・`)enumの作り方enumを生成する雑サンプルです。ProvidedEnums.Generatedこのように書くとenumを生成することができます。このシンプルな例ではField名はベタ書きの固定値を用いて生成されますが、任意の静的パラメータを渡すなりして任意の文字列ないし特定の外部ファイルの内容をもとに不特定多数のenumを生成できるようなものを作ることもできます。工夫をすることにより、それなりに使い道のあるTypeProviderに仕上げることができるかもしれません。ちなみに想像に難しくはないと思いますが、消去型のTypeProviderでenumを作ろうとしても、読んで字のなんとやら型情報が消えてしまいます!ので、enumを生成することができません。enumを作りたい場合は生成型で生成する必要があります。消去型と生成型の違いここにアリ!って感じですね。消去型と生成型の違いをシンプル且つわかりやすく説明するのにはよいサンプルでした。カスタム属性の付け方。付与しようFlagsAttributeを付与したenumを生成する方法から、カスタム属性を付与しつつ型を生成する方法についてみてみましょう。以下のように、CustomAttributeDataのインスタンスを作るヘルパーを用意しておくと便利です。オブジェクト式は便利ですね。}FlagsAttributeのようなコンストラクタで引数を要求しないAttribute向けには、たとえばこんな関数を定義しておきます(雑)。|])適当なパラメータからFlagsAttributeを付加したenumを作る雑サンプルです。[root])使い方はたとえばこうです。ProvidedFlagsEnums.Generated<"なし,火遁,風遁,水遁,雷遁,土遁,木遁,溶遁">サンプルなので雑に作りましたが、まじめに作ればそれなりに便利なものが作れそうな気はします。このように、生成する型に対してカスタム属性を付加することもできます。TypeProviderによって生成された型であるということを属性によってマークして明示する用途に使うこともできますし。応用の幅はありそうですね。|])安全性を無視できるのであれば、雑にこういうの作ったりするのもまぁアリかもですね。values)型安全絶対死守するマンを突き通して、ガチに頑張るのであればTryGetConstructor的なやつを作ったりしてまじめにやる感じかなあ?そのあたりはお好みでどうぞ。2016年11月22日TypeProviderあるあるすぎて、なるほどたし蟹!と思ったしだいです。静的パラメータをコードに直書きしたくないときは、TypeProviderから静的パラメータを作れればええやん!のパターンのやつ。以下のような感じのをつくっとけばサクッと実現できますね。])雑サンプルではありますが、こーゆーの用意しておくと便利かもーですね。してもええんじゃよお気づきの方もいるかもしれませんが、上記のFileReaderProviderでは、パターンマッチが不完全な記述があるため、警告がでてしまっています(!)該当のコードを切り出すと、ちょうどここです。配列に対するパターンマッチが不完全ですね。Quotations.Exprたったりもしますし、TypeProviderを作っていると、ArrayやListの要素に対して直にアクセスするシーンが頻出します。ラムダ式の引数から静的パラメータを取り出す場合、直にインデックス指定でアクセスして値を取り出すのが割と正攻法な気がしていますが、まあある程度は割り切ってしまって、雑パターンマッチで済ませてパターンマッチの記述をさぼるのもアリかなあと思います。不完全なパターンマッチの警告を無視してしまうのも方法としてはまあアリかなと。割り切れるか割り切れないかはまあ。