---GACの動作の知識不足が原因だったのですが、派生的に勉強になりました。---
文字列によるインスタンス化は
asm.CreateInstance(型名)
Activator.CreateInstance(type);
type.InvokeMember(Nothing, BindingFlags.CreateInstance,....)
AppDomain.CreateInstance
などがあります。
定石として
With Me 'GAC.アセンブリを読み込む
Dim a As [Assembly] = [Assembly].LoadWithPartialName("System.Drawing")
Dim name As String = "System.Drawing.Size"
Dim o As Object = a.CreateInstance(name)
Dim bl As Boolean = TypeOf o Is Size
Try
Dim sz As Size = CType(o, Size)
MessageBox.Show(String.Format(" {0},{1} ", sz.Width, sz.Height)) '>= 成功する
Catch ex As Exception
MessageBox.Show("GAC cast 失敗 : b1 = " + bl.ToString)
End Try
End With
があります..が LoadWithPartialName() は初回のコストが高い..そこで
直接 アセンブリ.DLLを読み込んでみましたら,コストが低くなりました. BUT!!!
Const ipath As String = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\"
'実際はipathは固定でなく GetCORSystemDirectory()で取得してます。
'APIコール使用に引っかかるものがあります. API以外に取得する方法ありませんか?(ついでの質問)
With Me
Dim a As [Assembly] = System.Reflection.Assembly.LoadFile(ipath + "\System.Drawing.dll")
Dim name As String = "System.Drawing.Size"
Dim o As Object = a.CreateInstance(name)
Dim bl As Boolean = TypeOf o Is Size
Try
Dim sz As Size = CType(o, Size)
MessageBox.Show(String.Format(" {0},{1} ", sz.Width, sz.Height))
Catch ex As Exception
MessageBox.Show("cast 失敗 : b1 = " + bl.ToString) '>= これが失敗するのでハマッテしまった。
End Try
End With
キャストができない?????
違いは..GAC経由か否か.
生成されたassemblyをみてみると
GlobalAssemblyCache: TrueかFalseの差とCodeBaseなどに差がある.
ということは, cast動作は 厳密名を考慮してキャストチェックしているんですね.
初回のコスト抑制を考えてみました
With Me 'LoadWithPartialNameは初回のコストが高いので改善
Dim t1 As Type = Type.GetType("System.Drawing.Size") ' これは失敗する
Dim t As Type = GetType(Size) ' (assembly取得のために Size.classを明記するので少しイヤ)
Dim a As [Assembly] = T.GetType.Assembly ' ' GetType(Size).Assembly としてもSizeを明記することになる...
Dim name As String = "System.Drawing.Size"
Dim o As Object = a.CreateInstance(name)
Dim bl As Boolean = TypeOf o Is Size
Try
Dim sz As Size = CType(o, Size)
MessageBox.Show(String.Format(" {0},{1} ", sz.Width, sz.Height))
Catch ex As Exception
MessageBox.Show("cast 失敗 : b1 = " + bl.ToString)
End Try
End With
コストは抑えられましたが, New()で初期設定ができないのと, assembyを引用する元のTypeの取得に getType(Size)を使っているのがすこしイヤです。
初期化付きNewを可能に改善
With Me
Dim t As Type = Size.GetType 'なんらかの形で Sizeの型が要る
Dim o As Object = t.InvokeMember(Nothing, BindingFlags.CreateInstance, Nothing, Nothing, New Object() {100, 300})
Try
Dim sz As Size = CType(o, Size)
MessageBox.Show(String.Format(" {0},{1} ", sz.Width, sz.Height))
Catch ex As Exception
MessageBox.Show(" cast 失敗 ")
End Try
End With
Sizeの型情報は何からの形で必要になるので, どの手法も長短がありそうです。