質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

2回答

7166閲覧

C#Classのpropertiesを再帰的に取得したいです。

picko

総合スコア52

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

0クリップ

投稿2016/07/22 07:37

こんにちは。いつもお世話になります。

Windows10, C#, Visual Studio 2015, WPFの組み合わせで開発しています。

次のような構造のClassのpropertiesを再帰的に取得したいです。
現在、1階層目の名前はとれました。
それぞれのpropertyのclass名をとれれば再帰的になりそうです。
しかし、p.を見てもp.Classとかは見あたりませんでした。
なにしろ階層が深いので、再帰で、最終的にtextboxのfull表記と内容を取得したいです。
class名をとる方法を教えてください。
よろしくお願いします。

C#

1namespace ApplicationWindow 2{ 3 public class MainViewModel : ViewModel 4 { 5 private void getProperties() 6 { 7 var vm = new MainWindowViewModel(); 8 var message = new TransinionMessage(vm, Transition.Modal, "ShowMainWindow"); 9 this.Messanger.Raise(message);//windowをmodalでopen 10 11 var strings = new List<string>(); 12 //ClassクラスのTypeオブジェクトを取得する 13 Type t = typeof(MainWindowViewModel); 14 15 // Propertyの一覧を取得する 16 PropertyInfo[] propertyInfos = t.GetProperties(); 17 18 foreach (PropertyInfo p in propertyInfos) 19 { 20 //名を表示 21 strings.Add(p.Name);//sub1ViewModel, sub2ViewModelを取得できる。 22 } 23 } 24 } 25 26 public class MainWindowViewModel : ViewModel 27 { 28 public MainWindowViewModel() 29 { 30 this.sub1ViewModel = new Sub1WindowViewModel(); 31 this.sub1ViewModel = new Sub1WindowViewModel(); 32 } 33 34 public Sub1ViewModel sub1ViewModel { get; } 35 public Sub1ViewModel sub2ViewModel { get; } 36 } 37 38 public class Sub1WindowViewModel : ViewModel 39 { 40 public Sub1WindowViewModel() 41 { 42 this.sub2Sub1ViewModel = new Sub2WindowViewModel(); 43 this.sub2Sub1ViewModel = new Sub2WindowViewModel(); 44 } 45 46 public Sub2ViewModel sub2Sub1ViewModel { get; } 47 public Sub2ViewModel sub2Sub2ViewModel { get; } 48 } 49 50 public class Sub2WindowViewModel : ViewModel 51 { 52 public Sub2WindowViewModel() 53 { 54 this.sub3Sub2Sub1ViewModel = new Sub3WindowViewModel(); 55 this.sub3Sub2Sub1ViewModel = new Sub3WindowViewModel(); 56 } 57 58 public Sub3ViewModel sub3Sub2Sub1ViewModel { get; } 59 public Sub3ViewModel sub3Sub2Sub2ViewModel { get; } 60 } 61 62 public class Sub3WindowViewModel : ViewModel 63 { 64 public string widthText { get; set; } 65 public string heightText { get; set; } 66 } 67} 68

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ozwk

2016/07/25 01:49

「textboxのfull表記」とは何でしょうか?
picko

2016/07/25 02:25

p.Name + "/" + p2.Name + "/" + p3.Name + "/"+ p4.Nameのようなかたちで取得できる情報です。
picko

2016/07/25 02:30

このapplicationというかwindowには、実際には36個のwidthTextとheightTextがあり、それぞれに値が入ります。そこで、 main-sub1-sub2-widthtext 360 main-sub1-sub2-heighttext 240 のように、どのtextboxの値がいくつか、を、組で取得したい、ということです。 言葉足らずでしたら、また追記します。
ozwk

2016/07/25 03:16 編集

必ず「main-sub1-sub2-width(height)text」の四階層ですか? また、Height、Width以外のプロパティは(プロパティなら無差別に、いまは存在しなくても、)取る必要がありますか?
picko

2016/07/25 04:05

今回は4階層です。下記にテストしている通りです。 ただ、せっかくつくるなら再帰のほうがよいと感じています。 height/width以外の値も同様です。 今回はheight/widthのみですが、ある程度拡張できるようにしたほうがよいなーとは思っています。
guest

回答2

0

ベストアンサー

こんにちは。

p.PropertyTypeで、そのメンバの型(Type)が取れるので、後は再帰的に呼び出せば良いと思います。

投稿2016/07/22 07:50

編集2016/07/22 07:51
Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

picko

2016/07/22 08:30

ありがとうございます。 foreach (PropertyInfo p in propertyInfos) { //名を表示 strings.Add(p.Name); Type tt = typeof(p.PropertyType); } だとエラーなのですが。。。。
Chironian

2016/07/22 08:36

PropertyTypeはType型ですので、Type tt = p.PropertyType;ですよ。
picko

2016/07/22 09:02

おお、そうでしたか。 ありがとうございます。できそうです。 また週明けに。
picko

2016/07/22 09:02

よい週末を。
picko

2016/07/25 01:33 編集

地道に値を確認しながら、TextBoxにたどり着きました。 これで、textboxのfull表記(string)はほぼ手に入りました。 しかし、変数vmに展開した現在表示中のTextBoxの値はとれてないです。 値を取得するには、あと何が必要でしょう?
picko

2016/07/25 01:35 編集

```C# var strings = new List<string>(); var laststrings = new List<string>(); //ClassクラスのTypeオブジェクトを取得する Type t = typeof(MainWindowViewModel); // Propertyの一覧を取得する PropertyInfo[] propertyInfos = t.GetProperties(); foreach (PropertyInfo p in propertyInfos.Where(p01 => Regex.Match(p01.Name, "ViewModel$").Success)) { //名を表示 strings.Add(p.Name); Type tt = p.PropertyType; PropertyInfo[] propertyInfo2s = tt.GetProperties(); foreach (PropertyInfo p2 in propertyInfo2s.Where(p02 => Regex.Match(p02.Name, "ViewModel$").Success)) { strings.Add(p.Name +"/"+ p2.Name); Type ttt = p2.PropertyType; PropertyInfo[] propertyInfo3s = ttt.GetProperties(); foreach (PropertyInfo p3 in propertyInfo3s.Where(p03 => Regex.Match(p03.Name, "ViewModel$").Success)) { strings.Add(p.Name + "/"+ p2.Name + "/"+p3.Name); Type tttt = p3.PropertyType; PropertyInfo[] propertyInfo4s = tttt.GetProperties(); foreach (PropertyInfo p4 in propertyInfo4s.Where(p04 => Regex.Match(p04.Name, "TextBoxText$").Success)) { strings.Add(p.Name + "/" + p2.Name + "/" + p3.Name + "/"+ p4.Name); laststrings.Add(p.Name + "/" + p2.Name + "/" + p3.Name + "/" + p4.Name + "\t"+ p4.ToString()); //p4のvalueをとれない。valueはインスタンスを作ったvmのほうにあるためか。vmのp4の値をとるにはどうすればいい? } } } } ```
picko

2016/07/25 01:35

うまくコメントをcodeにできませんでした。・・・。
Chironian

2016/07/25 02:46

Typeから追跡する場合、型情報だけしかありませんので、当然インスタンスにアクセスできません。 つまり、インスタンス(今回の場合vmから開始)も一緒に追跡する必要か有ります。 MainWindowViewModelのプロバティをpで枚挙してますね。 このpとvmを用いて、そのpのインスタンスを入手します。 この場合は、auto o=p.GetValue(vm)で、vmのプロバティpのインスタンスを獲得できると思います。 あとは、再帰的に繰り返せば、p4のvalueもとれる筈です。 かなり昔の記憶ですので、多少の相違があるかも知れません。その時はすいません。
picko

2016/07/25 04:19

ありがとうございます。 おっしゃるとおり型情報に加えてインスタンスを階層を追って取得して、該当のtextboxの中身を取得できました! ありがとうございました。
guest

0

こんにちは。
指定したクラスからプロパティの名前を再帰的に取得し、stringの配列にしたい、ということでよろしいでしょうか?
書いてみました。

csharp

1public static IEnumerable<string> GetProperties(Type type) 2{ 3 var props = type.GetProperties(); 4 return props.Select(p => p.Name) 5 .Concat(props.SelectMany(p => GetProperties(p.PropertyType))); 6}

GetProperties(typeof(MainWindowViewModel));で呼び出してください。

投稿2016/07/22 08:25

tamoto

総合スコア4105

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

picko

2016/07/25 01:41

ありがとうございます。 IEnumerable<string> allproperties = GetProperties(typeof(MainWindowViewModel)); として列挙できることを確認しました。 再帰、とてもsimpleできれいなコードです。 しかしながら、ほしいのは、 最終的にtextboxのfull表記と内容を取得したいです。 なのです。 まだこれだと、内容をとれてないです。 もう少しお付き合いいただけないでしょうか。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問