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

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

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

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

Q&A

解決済

3回答

662閲覧

C# 動的なタイプ変換時のプロパティ参照

komatta2018mt

総合スコア15

C#

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

0グッド

0クリップ

投稿2019/01/23 01:41

編集2019/01/23 02:44

{
"Result" : 0
, "ResultCnt": 2
, "Data": [
{ "AAAAA":1,"BBBBB":"2019/01/01","CCCCC":"ABCDE"}
, { "AAAAA":1,"BBBBB":"2019/01/01","CCCCC":"ABCDE"}
]
}

上記のjsonをDataTableに格納したいと思い、以下の処理を行いました。

lang

1 // ① 2 // デシリアライズ 3 var resData = (ClsXXXXXX)JsonDeserializer(resJson, typeof(ClsXXXXXX)); 4 5 // ② 6 // TestClassクラスのTypeオブジェクトを取得する 7 Type t = typeof(ClsXXXXXX); 8 9 // メソッドの一覧を取得する 10 PropertyInfo [] properties = t.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static); 11 foreach (PropertyInfo p in properties) 12 { 13 dt.Columns.Add(new DataColumn(p.Name)); 14 } 15 16 // 値設定 17 for (int i = 0; i < resData.Data.Count; i++) 18 { 19 DataRow row = dt.NewRow(); 20 foreach (PropertyInfo p in properties) 21 { 22 // データテーブルに値を設定 23 row[p.Name] = p.GetValue(resData.Data[i]); 24 } 25 // 行追加 26 dt.Rows.Add(row); 27 }

上記はうまく動いているのですが、jsonのDataの部分は複数フォーマットあり、ClsXXXXXX を動的に変更したく、②以降を関数としたいのですがうまくできません。
構文エラーとなる箇所について、どのように記述すればよいかお教え願えませんでしょうか。
var resData = (ClsXXXXXX)JsonDeserializer(resJson, typeof(ClsXXXXXX));
resDataを引数(data)として渡す↓

lang

1 public DataTable SetDataTable(Object data) 2 { 3 // 戻り値用 4 DataTable dt = new DataTable(); 5 6 //TestClassクラスのTypeオブジェクトを取得する 7 Type t = data.GetType(); 8 9 //メソッドの一覧を取得する 10 PropertyInfo[] properties = t.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static); 11 foreach (PropertyInfo p in properties) 12 { 13 dt.Columns.Add(new DataColumn(p.Name)); 14 } 15 16 // 値設定 17 for (int i = 0; i < data.Data.Count; i++) // data.Data が構文エラーとなる 18 { 19 DataRow row = dt.NewRow(); 20 foreach (PropertyInfo p in properties) 21 { 22 // データテーブルに値を設定 23 row[p.Name] = p.GetValue(data.Data[i]); // data.Data が構文エラーとなる 24 } 25 // 行追加 26 dt.Rows.Add(row); 27 } 28 29 // 戻り値 30 return dt; 31 }

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

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

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

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

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

papinianus

2019/01/23 01:51

そのClsXXXXたち(必ずDATAをもつ?)に共通の基底クラスか、DATAをもっていることを保証できるインターフェイスは実装していないということでしょうか?
komatta2018mt

2019/01/23 02:45

dodox86様 ご指摘ありがとうございます。 修正いたしました。
komatta2018mt

2019/01/23 02:58

papinianus様 ご回答ありがとうございます。 ClsXXXXたちは必ずDATAを持っています。 DATAを持った基底クラスを作成し、継承したクラスの方でDATAをoverrideしようとしたのですが、型が違う為、できませんでした。 基底クラスのDATAは List<Object> Data 継承したクラスのDATAは List<ClsXXXXDATA> Data
papinianus

2019/01/23 03:08

回答をかきましたが、ClsXXXXDATAが、Dataプロパティをもっているというのは変(自分のクラスが自分のクラス型の配列を持つのでしょうか?)に思いました。resDataの型と、resDataのDataに入っている1要素の型に混同があるように思いました。
guest

回答3

0

よくわかっていないけど、

public class Result<T> { public int Result{get;set;} public int ResultCnt{get;set;} public T[] List {get;set;} }

こういうのにして、

JsonConvert.DeserializeObject<Result<T>>(jsonText)

とかすればいいじゃないかな。(Json.net使用)

投稿2019/01/23 03:15

kiichi54321

総合スコア1984

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

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

komatta2018mt

2019/01/23 04:13

kiichi54321様 ご回答ありがとうございます。 ジェネリックメソッドとすることで、なんとか解決いたしました。
guest

0

ベストアンサー

dynamicでもできるかもしれないけど、この用途ではあまり…

私も混乱していたのですが、質問者様にも混乱がありませんか?

SetDataTableを呼び出す(利用する)ときに、SetDataTable(resData.Data)とするはずなので、forの中でdata.Dataとすることはないと思います。

public DataTable SetDataTable(Object data)のdataはもともと、resData.Dataにあったものですよね?(resData自身ではない)
しかも、resData.Data自身、配列様なので、Type t = data.GetType();とすると、ClsXXXX[]が取得できてしまいませんかね?

ジェネリックメソッドにして、public DataTable SetDataTable<T>(T[] data)という宣言にするほうがよいように思います。
(これなら、SetDataTable(resData.Data)という利用ができるはず)

投稿2019/01/23 03:07

papinianus

総合スコア12705

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

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

komatta2018mt

2019/01/23 04:10

ご指摘のとおり、SetDataTableに渡す値を間違えておりました。 大変申し訳ございません。 お教えいただきました様に、ジェネリックメソッドに修正したところ、うまく動作いたしました。 ありがとうございました。
guest

0

System.GetTypeメソッドであればクラス名文字列からTypeが得られるので、これをうまく利用して関数/メソッド化できませんか。

System.GetType(String, Boolean)

投稿2019/01/23 01:51

dodox86

総合スコア9183

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

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

komatta2018mt

2019/01/23 04:13

dodox86様 ご回答ありがとうございます。 ジェネリックメソッドとすることで、なんとか解決いたしました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問