- こねこばす
- 会議室デビュー日: 2005/12/27
- 投稿数: 9
|
投稿日時: 2006-02-01 15:07
こんにちは。いつも参考にさせていただいています。
ある自作クラスにプロパティが複数作成してあり、
プロパティ名をkeyに動的にプロパティの取得・値の反映を行いたいと思っております。
Reflectionを使用して色々試してみたのですが、
プロパティを取得することができませんでした。
もし、ご存知の方がいらっしゃいましたらご教授お願いします。
以下サンプルです。
------------------------------------------
namespace MyNamespaace
{
[Serializable]
public class MyClass
{
private int _property1;
private int _property2;
public int Property1
{
get { return _property1; }
set { _property1 = value; }
}
public int Property2
{
get { return _property2; }
set { _property2 = value; }
}
Public void SetValue(string propertyName, string propertyValue)
{
Type myType = typeof(int);
FieldInfo[] fis = myType.GetFields();
foreach(FieldInfo fi in fis)
{
if(fi.Name.Equals(propertyName)) ←ここで取得できる項目は「MaxValue・MinValue」になっています。
fi.SetValue(fi, propertyValue);
}
}
}
------------------------------------------
|
- 囚人
- ぬし
- 会議室デビュー日: 2005/08/13
- 投稿数: 1019
|
投稿日時: 2006-02-01 15:23
引用: |
|
Type myType = typeof(int);
|
int だから。
引用: |
|
FieldInfo[] fis = myType.GetFields();
|
PropertyInfo info = myType.GetProperty( propertyName );
引用: |
|
fi.SetValue(fi, propertyValue);
|
ん〜、設定する値まで String だとチョト無理なような…。
コード: |
|
public void SetValue( string propertyName, int propertyValue )
{
Type myType = GetType();
PropertyInfo info = myType.GetProperty( propertyName );
info.SetValue( this, propertyValue, BindingFlags.Public | BindingFlags.SetProperty, null, null, null );
}
|
_________________ 囚人のジレンマな日々
|
- じゃんぬねっと
- ぬし
- 会議室デビュー日: 2004/12/22
- 投稿数: 7811
- お住まい・勤務地: 愛知県名古屋市
|
投稿日時: 2006-02-01 16:11
引用: |
|
囚人さんの書き込み (2006-02-01 15:23) より:
ん〜、設定する値まで String だとチョト無理なような…。
|
ん〜、無理なの?
コード: |
|
public void SetValue(string propertyName, object setValue) {
System.Type hType = this.GetType();
System.Reflection.PropertyInfo hInfo = hType.GetProperty(
propertyName,
System.Reflection.BindingFlags.Public |
System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.DeclaredOnly
);
if (hInfo == null) {
throw new System.ArgumentException("存在しないプロパティです。", propertyName);
}
if (! hInfo.CanWrite) {
throw new System.ArgumentException("読み取り専用のプロパティです。", propertyName);
}
try {
hInfo.SetValue(this, setValue, null);
} catch (System.Exception ex) {
throw ex;
}
}
|
相変わらず、かなり適当ですが。
_________________ C# と VB.NET の入門サイト
じゃんぬねっと日誌
|
- 囚人
- ぬし
- 会議室デビュー日: 2005/08/13
- 投稿数: 1019
|
投稿日時: 2006-02-01 16:27
無理っぽいですね。
じゃんぬさんの出されたコードだと、Int32 が入ってくれる可能性があるのでそのときはOK。他の型だと吹っ飛びます。(そのときはそのときで例外スローして仕舞いってのならOKです)
質問者のコードだと、String 固定なので必ず吹っ飛びます。(例のコードのプロパティが Int32 だから。Int32.Parse() すればいいけど、リフレクションしてる意味薄れますよね)
※吹っ飛ぶ → 実行時エラー。
プロパティを名前で探し出し、設定する値も文字列から得たいのかな?
プロパティの型が様々だというなら、何らかの手段を以って「設定する値の型」も得ないと駄目っぽいですね。
_________________ 囚人のジレンマな日々
|
- じゃんぬねっと
- ぬし
- 会議室デビュー日: 2004/12/22
- 投稿数: 7811
- お住まい・勤務地: 愛知県名古屋市
|
投稿日時: 2006-02-01 17:06
引用: |
|
囚人さんの書き込み (2006-02-01 16:27) より:
無理っぽいですね。
じゃんぬさんの出されたコードだと、Int32 が入ってくれる可能性があるのでそのときはOK。
|
検証したコード。
コード: |
|
private static void MakiMakiLove() {
Jeanne.Ini.IniFile hIniFile = new Jeanne.Ini.IniFile();
hIniFile.FilePath = "MakiMakiLove.ini";
hIniFile.DefaultValue = "DefaultValue";
hIniFile.BufferSize = 128;
hIniFile.SetValue("FilePath", "FilePath は変更された");
hIniFile.SetValue("DefaultValue", "DefaultValue は変更された");
hIniFile.SetValue("BufferSize", 256);
Console.WriteLine(hIniFile.FilePath);
Console.WriteLine(hIniFile.DefaultValue);
Console.WriteLine(hIniFile.BufferSize);
}
|
コード: |
|
結果 :
FilePath は変更された
DefaultValue は変更された
256
|
引用: |
|
他の型だと吹っ飛びます。(そのときはそのときで例外スローして仕舞いってのならOKです)
|
そっちのことですか... orz
コンパイル解決できない手法をとっている以上、強い型意識はしないで良いという意図になるはずです。
イヤならコレクションか配列を使うべきだと思います。
# 古い話、Properties[] As Property には型はない。
_________________ C# と VB.NET の入門サイト
じゃんぬねっと日誌
|
- じゃんぬねっと
- ぬし
- 会議室デビュー日: 2004/12/22
- 投稿数: 7811
- お住まい・勤務地: 愛知県名古屋市
|
投稿日時: 2006-02-01 17:16
引用: |
|
囚人さんの書き込み (2006-02-01 16:27) より:
プロパティの型が様々だというなら、何らかの手段を以って「設定する値の型」も得ないと駄目っぽいですね。
|
一応、GetSetMethod やらで GetParameters して PrameterType から取得できますが、
先の理由で、やっぱりあまり意味はないですね...
_________________ C# と VB.NET の入門サイト
じゃんぬねっと日誌
|
- なちゃ
- ぬし
- 会議室デビュー日: 2003/06/11
- 投稿数: 872
|
投稿日時: 2006-02-01 18:06
一応、ごく簡単にやってしまうのであれば…
普通(かどうかは分かりませんが)、PropertyTypeで型を調べて、
TypeDescriptorからTypeConverterを取得してごにょごにょ。
そんなことやるならプロパティもTypeDescriptorからとったほうが
いいかもしれませんが。
|
- nanbu
- 大ベテラン
- 会議室デビュー日: 2004/08/19
- 投稿数: 178
|
投稿日時: 2006-02-01 18:51
引用: |
|
なちゃさんの書き込み (2006-02-01 18:06) より:
一応、ごく簡単にやってしまうのであれば…
普通(かどうかは分かりませんが)、PropertyTypeで型を調べて、
TypeDescriptorからTypeConverterを取得してごにょごにょ。
そんなことやるならプロパティもTypeDescriptorからとったほうが
いいかもしれませんが。
|
南部です。
上記ごにょごにょをコード化するとこんなイメージです。
デザイン時以外では使ったことないですが。
コード: |
|
private void button1_Click(object sender, System.EventArgs e)
{
//格納するデータ
StringDictionary propTable = new StringDictionary();
propTable.Add("IntValue", "A");
propTable.Add("DateValue", "2006/2/1");
Test t = new Test();
PropertyDescriptorCollection props =
System.ComponentModel.TypeDescriptor.GetProperties(t);
foreach(PropertyDescriptor prop in props)
{
try
{
prop.SetValue(t, prop.Converter.ConvertFrom(propTable[prop.Name]));
continue;
}
catch(Exception){} //例外処理割愛
prop.ResetValue(t);
}
MessageBox.Show(t.ToString());
}
//テスト用クラス
public class Test
{
int a;
DateTime b;
[DefaultValue(10)]
public int IntValue
{
get { return a; }
set { a = value; }
}
public DateTime DateValue
{
get { return b; }
set { b = value; }
}
public override string ToString()
{
return string.Format("a = {0}, b={1}", a, b);
}
}
|
|