DOBON.NET DOBON.NETプログラミング掲示板過去ログ

文字列でプロパティを設定する方法

環境/言語:[VB.NET]
分類:[.NET]

はじめまして。VB.Net初心者です。
今困っていることをお教えいただければと思っております。
よろしくお願いいたします。

「文字列で指定されたメソッドを実行する」という記事を
拝見いたしました(.Net Tips>>その他のTips)。
Typeのインスタンスを作って、それからInvokeすればいい、
と言うことはわかりました。

同じように、プロパティの設定は、SetProperty()で実行できることも
わかったのですが、
設定するプロパティの値が、文字列ではない型のものだとして、
その値をファイルから読みこんでセットする場合、何か共通の手立ては
ないでしょうか?

たとえば、FormのControlのプロパティ定義したファイルがあるとします。

Name="TxtHOGE"
Text="ほげほげ"
Location="{X=120, Y=100}"

と記述したテキストファイルから、コントロールオブジェクトを
作りたいのです。


Nameは、以下のように
dim cntl as Control = new Control()
dim ty as Type = Type.GetType(cntl)
Dim pr As PropertyInfo = ty.GetProperty("Name")
pr.SetValue(cntl, "TxtHOGE", Nothing)

とすれば、コントロールcntlのnameに"TxtHOGE"をセットする
ことができました。Textも同様です。
(ここでは文字列を直接コーディングしていますが、
 実際はファイルをStringの変数に読み込み、それを指定しました)

しかし、Locationは、Pointクラスのため、
ファイルに記述された"{X=120, Y=100}" からPointを
作らなければなりません。

このような場合、
この文字列を構文解釈するメソッドを個別に作らないと
ならないのでしょうか?

ちなみに、
この"{X=120, Y=100}" という文字列は、Locationのインスタンスの
ToString()メソッドを実行した結果です。
.Netのクラスには、ToString()はありますが、
FromString()といったメソッドは一般的には無いのでしょうか?
>この文字列を構文解釈するメソッドを個別に作らないと
> ならないのでしょうか?

ファイルに型情報も持たせてしまうというのはどうでしょう?
例えば、
Name="string","hoge"
Location="Point","120,100"
■No15224に返信(trapemiyaさんの記事)

trapemiyaさま、ありがとうございます。

> ファイルに型情報も持たせてしまうというのはどうでしょう?
> 例えば、
> Name="string","hoge"
> Location="Point","120,100"

この場合、
それぞれの型を意識して、Case文に分けるような感じでしょうか?

−−−−−−−−−−−−−−−
dim typeName as String = '上記ファイルからタイプを取り出したもの

select Case typeName
Case "String"
'先ほどの方法

 Casel "Point"
'文字列からX値とY値を求める
dim xy as string() = Split("120,100", New Char() {","c})

'文字配列を、Integerに変換する
   dim x as Integer = CInt (xy(0))
dim y as Integer = CInt (xy(1))

'Pointを作る
dim p as Point = new Point (x, y)

'このあと、pをプロパティにセットする
'(先ほどの方法)

−−−−−−−−−−−−−−−

 上記の場合、120,100という文字列を、Point型のインスタンスに
 するために、文字列から数値を取り出さなければできないように
 思うのですが、

 new Point ("120,100")

というコンストラクタがあるかのような手続きは
 できないものでしょうか?

 ・・・かなりワガママな気がしてきました (^^;)

 先ほどCType()というメソッドを見つけたので
 これで、
CType ("120,100", Point )とやったのですが、
 これはビルドエラーでした。
>それぞれの型を意識して、Case文に分けるような感じでしょうか?

その通りです。

>というコンストラクタがあるかのような手続きは
> できないものでしょうか?

Activator.CreateInstanceなんかを使うとそれに近いことができるかもしれませんが、コンストラクタの引数が違うので、いずれにしてもCaseで分けることになると思います。であれば、最初から普通にインスタンスを作成すればいいんじゃないかと思います。

> CType ("120,100", Point )とやったのですが、
>  これはビルドエラーでした。

キャストはあくまで継承関係上で行き来するものです。自分より上のクラスへのキャスト以外は普通はしません。(ダウンキャストはしない)
キャストは万能な型変換ではありませんし、そのようなものは存在しません。
上記はstring型からPoint型へキャストしようとして失敗しています。
■No15229に返信(trapemiyaさんの記事)

> >それぞれの型を意識して、Case文に分けるような感じでしょうか?
>
> その通りです。
>
> Activator.CreateInstanceなんかを使うとそれに近いことができるかもしれませんが、コンストラクタの引数が違うので、いずれにしてもCaseで分けることになると思います。であれば、最初から普通にインスタンスを作成すればいいんじゃないかと思います。

なるほど、よくわかりました。
ありがとうござます。
trapemiyaさまがご指示くださったように、型もファイルで
指定して、Case文でわけるようにしました。


>> CType ("120,100", Point )とやったのですが、
>> これはビルドエラーでした。
>
> キャストはあくまで継承関係上で行き来するものです。
> 自分より上のクラスへのキャスト以外は普通はしません。
> (ダウンキャストはしない)

そうだったのですか!
常識知らずでした。これも勉強になりました。
どうもありがとうございました。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板