オブジェクト型をどうにかキャストしてみる〜objectな配列を取り出す

  • 2011.07.14 Thursday
  • 12:48
 
Dim oItem As Object = New Object(){New Int32(){1,2,3}, New Int32() {4,5,6}}
Dim iItem() As Int32 = oItem(0)

このソースは普通にiItemに値がキャストされて格納されると思う。


いま、JSONである構造体にオプションデータ(データは任意なのでObject型としている)を格納する変数を作ったのだが、
たとえば、オプションデータに配列(Array型)が入った場合、その変数すべてがオブジェクト型(Array型のオブジェクト)で格納されてしまうため、
 
iItem = oItem(0)

とオプションデータを型の決まった変数にキャストすると
 
型 'System.Object[]' のオブジェクトを型 'System.Int32[]' にキャストできません。

と怒られてしまう


どうしたらいいのか?

キャストすると言えば、型変換をしてみるということで、
 
iItem = CType(oItem(0), Int32())

を試したら、だめ
 
iItem = DirectCast(oItem(0), Int32())

を試してみてもだめ

うーむ、なかなか、Objectな配列はくせ者だ


残るはループで回して取り出すという考えもあるけれど(これが確実)、
数カ所に取り出すところがあるので、できればソースはシンプルに済ませたい。


調べていたら、いつもお世話になっているここにたどり着いた

配列とArrayListを変換する


なるほど、こういう時こそ、LINQの機能を使えばいいじゃないか

早速、
 
Dim iItem() As Int32 = (From cItem As Int32 In oItem(0) Select CInt(cItem)).ToArray

と書いてみるが・・・

今度はoItem(0)の部分が

'Object' の式はクエリ不可能です。LINQ プロバイダに対してアセンブリ参照や名前空間インポートが不足していないことを確認してください。

とエラー


ならば、配列(Array型)としてキャストさせたソースに書き直してみる
 
Dim oItem As Object = New Object() {New Object() {123}, New Object() {456}}'すべてオブジェクトなデータ
Dim iItem() As Int32 = (From cItem As Int32 In CType(oItem(0), Array) Select CInt(cItem)).ToArray

これでoItemの値をiItemへキャストできました。
 
iItem = (From cItem As Int32 In DirectCast(oItem(0), Array) Select CInt(cItem)).ToArray

とDirectCastを使ってみても問題はないようだ。


ちなみに、オブジェクトの中に数値型以外が入っているとエラーするので、
 
New Object() {1"abc"3}
 
String "abc" から型 'Integer' への変換は無効です。
 
iItem = (From cItem As Object In CType(oItem(0), Array) Where IsNumeric(cItem) = True Select CInt(cItem)).ToArray

とIsNumericを入れて上げてもよい(このままだと配列数が変わってしまうが・・・)


適当な解決策なので、もっと効率の良い方法があるかもしれない。


追記
上の例は配列の配列(ジャグ配列)のObjectへのキャストでしたが、
普通は1次の配列を入れるかと思う。そちらを先に書けば良かったかなと思ったので、追記すると、

例えば、ListBoxのAddRangeなどの場合、元がObject型やString型の配列であれば、
AddRangeはそのままできますが、例えば、Integer型や構造体などを入れる場合、
やはり上のようなキャストエラーが出てしまう。

そういった場合は、Linqを使ってObject型の配列に置き換えて上げればよい。
ソースを書くと、
 
Dim Source() As Int32 = New Int32() {1I, 2I, 3I, 4I, 5I}
Dim oItem() As Object = (From eItem As Int32 In Source Select CObj(eItem)).ToArray
‌ 
Call Me.ListBox1.Items.AddRange(oItem)

といった感じになる。



関連投稿

いまさらJSONしてみる〜VB2008でJSON形式を使う
いまさらJSONしてみる〜クラスや構造体をJSONしてみる
いまさらJSONしてみる〜配列を作ってみる。
いまさらJSONしてみる〜難読化とクラスのデシリアライズ

自作構造体の配列の特定要素をToArrayしたい
 
コメント
コメントする








    
この記事のトラックバックURL
トラックバック

calendar

S M T W T F S
     12
3456789
10111213141516
17181920212223
24252627282930
<< September 2017 >>

search this site.

よく使う、検索される投稿

categories

アマゾン

楽天

selected entries

archives

recent comment

recent trackback

profile


※当ブログはリンクフリーですが、 取材や雑誌等で掲載される場合は、事前にお知らせください

others

mobile

qrcode

powered

無料ブログ作成サービス JUGEM