.NETのジェネリクス解決
.NETのジェネリクス解決が意外とめんどくさい
型にジェネリクスがついている場合と関数にジェネリクスがついている場合がある
例えばListなんかは型にジェネリクスがついているのでこんな感じ
Dim list = GetType(List(Of )) Dim list_add = list.GetMethod("get_Item") ' この時点で「T List(T).get_Item(int32)」 Dim list_str = list.MakeGenericType({GetType(String)}) Dim list_str_add = list_int32.GetMethod("get_Item") ' これで「string List(int32).get_Item(int32)」
Dim list = GetType(List) Dim list_add = list.GetMethod("get_Item") ' この時点で「T List.get_Item(int32)」 Dim list_str_add = list_add.MakeGenericMethod({GetType(String)}) ' これで「string List.get_Item(int32)」
list_addだけ見たらほぼ違いがないっていう
レシーバがIsGenericTypeなら型のジェネリクス解決して
list_addがIsGenericTypeなら関数のジェネリクス解決する感じ?
とりあえずList型だけ動かしたかったのでレシーバ決め打ちで解決をしたけど、型と関数が両方ジェネリクスだとどーしたらよかんべか
var xs = List(Int)() List.Add(xs, 10) var a0 = List.get_Item(xs, 0) # ←例えばApplyじゃなくてこの第一引数を使う?
型と関数に別々のジェネリクスを設定したケースを用意して同時にApplyできるか考えよう
・・・そんな都合のいいクラスあったか?
.NETのメソッドが呼べた
.NETのメソッドが呼べるようになった
作っている言語にメソッドなんて概念をつけていないので「型.メソッド(引数)」の並びを「メソッド(型, 引数)」に変えて関数コールするようにした
幸いCILではどっちでも一緒だしね
ちょっと面倒なのが名前空間
「DateTime.Parse(a)」は「DateTime::Parse(a)」と「Parse(DateTime, a)」の2種類の解釈ができるから「DateTime」が型なのか名前空間なのか判定しなきゃいけない
でもメソッドなんてないので、便宜上↓みたいなイメージに展開している
namespace System struct DateTime var x = xxxxx namespace DateTime sub Parse(s : String) DateTime xxxxx sub ToString(self : DateTime, s : String) String xxxxx
これじゃDateTimeが型なのか名前空間なのか型付けしてみるまでわかんない・・・
自分のソース部分だけなら型と同名の名前空間なんかコンパイルエラーにしちゃえばいいけど.NETアセンブリ読み込みのところだけは、まぁできるようにしておく
おかげでシンタックスシュガーの変換が型のinfer中に行うはめになって、どんより
.NETのコンストラクタが呼べた
.NETのコンストラクタを呼べるようになった
値型でコンストラクタの引数無しはinitobjなの?
とりあえずnewobjしか対応してない、DateTimeを引数無しで作成することができへんけどまぁええわ
コンストラクタの解決はめんどくさかったのでこんな風にしておいた
デフォルト引数も可変長引数も当面無視する感じ
TypeInfo.GetConstructors.FindFirst( Function(ctor) ctor.GetParameters.And( Function(arg, i) root.LoadType(arg.ParameterType.GetTypeInfo) Is args(i)))
しかし、デフォルト引数ってCILでは呼び出し側がスタックにプッシュするんやな
呼び出された側かCILがあんじょうやってくれるもんやと思ってた・・・
gitのお勉強ついでにブランチを切ってnon-fast-forwardでマージした
前回はfast-forwardでマージしちゃってよくわかんなくなったので、今回はいい感じにコミットグラフが残った
まぁ別にmaster一本でも困らないんだけど、ヨカッタヨカッタ
WMI Win32_Processorが使えない
最近Windows7→10にした一台でアップデートしたとたんWin32_Processorが使えなくなってた
LoadPercentageがずっとnullになる感じ
他のWin10マシンでは問題ないので原因はよくわかんない
アップデート後にCPUの使用ログを見たらずっと0%のままなので何事かと思ったら・・・
とりあえずWin32_PerfFormattedData_PerfOS_Processorは使えるようなので
PercentProcessorTimeで置き換えるようにしてみた
タスクマネージャのCPU使用率と数ポイント誤差があるけどまぁええやろ
var locater = WScript.CreateObject("WbemScripting.SWbemLocator"); var service = locater.ConnectServer(); function get_cpu(service) { var xs = new Enumerator(service.ExecQuery("Select * From Win32_Processor")); for(; !xs.atEnd(); xs.moveNext()) { if(xs.item().LoadPercentage == null) {break;} return(xs.item().LoadPercentage); } xs = new Enumerator(service.ExecQuery("Select * From Win32_PerfFormattedData_PerfOS_Processor Where Name = '_Total'")); for(; !xs.atEnd(); xs.moveNext()) { return(xs.item().PercentProcessorTime); } return(""); }
全くもう、ようわからん
昨日今日とちゃんと動いたので良しとしよう