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

[ 最新記事及び返信フォームをトピックトップへ ]

■34283 / inTopicNo.1)  動的にプロパティや変数の値の取得
  
□投稿者/ ゆみと 一般人(1回)-(2019/07/28(Sun) 12:46:50)
  • アイコン環境/言語:[VS2010 C#] 
    分類:[.NET] 

    いつも参考にさせて頂いています。

    生成されたインスタンスに対して動的にプロパティや変数の値を取得を行いたいです。

    イメージ的には
    string getname = "Dai"."syou_A"."nameA";

    のような形で取得出来ないでしょうか。

    入れ子の入れ子?(言い方が正しいか分かりません)になった場合よく分からなくなってきました。

    public class Dai
    {
    public syou_A = new syouA();

    public syou_B {get; set;}

    public Dai()
    {
    this.syou_B = new syouB();
    }
    }

    public class syouA
    {
    public string nameA = nameA;
    public object ageA = ageA;
    }

    public class syouB
    {
    public string nameB { get; set;}
    public object ageB { get; set;}
    }

    public class Test
    {
    private dai = new Dai();

    public Test()
    {
    dai = new Dai();

    dai.syou_A.nameA = "なまえ";
    dai.syou_A.ageA = "99";

    dai.syou_B.nameB = "ナマエ";
    dai.syou_B.ageB = "0";
    }

    public void doutekiniSyutoku()
    {
    string getname = "Dai"."syou_A"."nameA";
    }
    }
マルチポストを報告
違反を報告
引用返信 削除キー/
■34284 / inTopicNo.2)  Re[1]: 動的にプロパティや変数の値の取得
□投稿者/ 魔界の仮面弁士 大御所(1234回)-(2019/07/28(Sun) 15:24:32)
  • アイコンNo34283に返信(ゆみとさんの記事)
    > 生成されたインスタンスに対して動的にプロパティや変数の値を取得を行いたいです。
    『何のために』そのようなことがしたいのでしょうか?

    理由如何によって、必要な対処方法も変わってくるかと
    思いますが、とりあえず幾つか例を挙げてみると…

    案1) 動的にアクセスできるよう、DynamicObject から継承するようにする
    案2) ExpandoObject クラスを使って dynamic でアクセスするようにする
    案3) Dictionary<string, Dictionary<string,dynamic>> を使う
    案4) XDocument で階層化データ構造を表すようにする
    案5) リレーション付き DataSet を使う(型付き DataSet でも可)
    案6) Microsoft.VisualBasic.Interaction.CallByName メソッドで呼び出す
    案7) リフレクションを通じて呼び出す
違反を報告
引用返信 削除キー/
■34285 / inTopicNo.3)  Re[2]: 動的にプロパティや変数の値の取得
□投稿者/ ゆみと 一般人(4回)-(2019/07/29(Mon) 11:30:25)
  • アイコン魔界の仮面弁士さん

    いつもありがとうございます。

    難しい事は考えず以下の方法で行います。

    /*syouAの場合*/
    FieldInfo field = t1.GetField("syou_A");

    var obj = field.GetValue(dai);

    Type t = obj.GetType();

    FieldInfo fieldy2 = t.GetProperty("nameA");

    string buff = fieldy2.GetValue(obj, null).ToString();

    /*syouBの場合*/
    PropertyInfo property = t1.GetProperty("syou_B");

    var obj = property.GetValue(dai, null);

    Type t = obj.GetType();

    PropertyInfo property2 = t.GetProperty("nameB");

    string buff = property2.GetValue(obj, null).ToString();

    以上

    No34284に返信(魔界の仮面弁士さんの記事)
    > ■No34283に返信(ゆみとさんの記事)
    >>生成されたインスタンスに対して動的にプロパティや変数の値を取得を行いたいです。
    > 『何のために』そのようなことがしたいのでしょうか?
    >
    > 理由如何によって、必要な対処方法も変わってくるかと
    > 思いますが、とりあえず幾つか例を挙げてみると…
    >
    > 案1) 動的にアクセスできるよう、DynamicObject から継承するようにする
    > 案2) ExpandoObject クラスを使って dynamic でアクセスするようにする
    > 案3) Dictionary<string, Dictionary<string,dynamic>> を使う
    > 案4) XDocument で階層化データ構造を表すようにする
    > 案5) リレーション付き DataSet を使う(型付き DataSet でも可)
    > 案6) Microsoft.VisualBasic.Interaction.CallByName メソッドで呼び出す
    > 案7) リフレクションを通じて呼び出す
違反を報告
引用返信 削除キー/
■34286 / inTopicNo.4)  Re[1]: 動的にプロパティや変数の値の取得
□投稿者/ 魔界の仮面弁士 大御所(1235回)-(2019/07/29(Mon) 11:57:24)
  • アイコン2019/07/29(Mon) 12:00:34 編集(投稿者)

    No34283に返信(ゆみとさんの記事)
    > 入れ子の入れ子?(言い方が正しいか分かりません)になった場合よく分からなくなってきました。

    質問文の C# 文法がおかしいので、何がやりたいのか曖昧で…。

    まずは【Dai クラス】の問題点から。

    > public class Dai
    > {
    >   public syou_A = new syouA();
    >   public syou_B {get; set;}
    >   public Dai()
    >   {
    >     this.syou_B = new syouB();
    >   }
    > }

    フィールド変数やプロパティの「型」を書き忘れているので、
    そもそも文法違反です。最低でもこうなるはずですよね。

    public class Dai {
      public syouA syou_A = new syouA();
      public syouB syou_B {get; set;}
      public Dai() { this.syou_B = new syouB(); }
    }



    さて次は【syouA クラス】の問題点。

    > public class syouA
    > {
    >  public string nameA = nameA;
    >  public object ageA = ageA;
    > }

    変数宣言と同時に、その変数を右辺に使うことは出来ません。
    未初期化変数へのアクセスということで、コンパイルエラーとなります。

    仮に同じ変数自身でなかったとしても、自身のインスタンスメンバーを
    フィールド初期化子に使うのは NG なので、たとえば
      public object ageA = "ageA";
      public string nameA = ageA;
    というのも NG ですね。


    最後は【Test クラス】の問題点については、
    Dai クラスのものと同じ理由なので割愛。

    > public class Test
    > {
    >   private dai = new Dai();


    質問の本題部となるのは、この部分ですね。

    > public void doutekiniSyutoku()
    > {
    >   string getname = "Dai"."syou_A"."nameA";
    > }



    No34284 に追記(魔界の仮面弁士)
    > 案1) 動的にアクセスできるよう、DynamicObject から継承するようにする
    > 案2) ExpandoObject クラスを使って dynamic でアクセスするようにする

    これらは「動的にメンバーを追加・取得することが目的」の場合に使うものです。

    案1 は継承が必要になりますが、動的なメンバー指定に応じて
    ファイルやデータベースに検索に行くような、MVC 的な利用が可能です。

    単純な読み書き向けだけなら、案2 でも十分です。以下サンプル。


    class Program
    {
      private static dynamic dai;
      static void Main()
      {
        // 動的なメンバー生成
        dai = new ExpandoObject();
        dai.syou_A = new ExpandoObject();
        dai.syou_B = new ExpandoObject();
        dai.syou_A.nameA = "なまえ";
        dai.syou_B.nameA = "ナマエ";
        dai.syou_A.ageA = "99";
        dai.syou_B.ageB = "0";

        // メンバー名出のアクセス
        Console.WriteLine(動的取得("syou_A", "nameA"));

        Console.ReadLine();
      }

      public static dynamic 動的取得(string member1, string member2)
      {
        dynamic syou = ((IDictionary<string, object>)dai)[member1];
        return ((IDictionary<string, object>)syou)[member2];
      }
    }


    > 案3) Dictionary<string, Dictionary<string,dynamic>> を使う
    > 案4) XDocument で階層化データ構造を表すようにする
    > 案5) リレーション付き DataSet を使う(型付き DataSet でも可)

    こっちは System.Dynamic に頼らない方法なので、C#2005 世代でも利用可能。



    > 案6) Microsoft.VisualBasic.Interaction.CallByName メソッドで呼び出す
    > 案7) リフレクションを通じて呼び出す

    元クラスの定義を変更したくないならこっち。
    No34285 は案7 に相当しますね。
違反を報告
引用返信 削除キー/
■34287 / inTopicNo.5)  Re[2]: 動的にプロパティや変数の値の取得
□投稿者/ ゆみと 一般人(5回)-(2019/07/30(Tue) 10:02:06)
  • アイコン2019/07/30(Tue) 20:45:44 編集(投稿者)
    2019/07/30(Tue) 20:45:22 編集(投稿者)

    魔界の仮面弁士さん

    いつもありがとうございます。

    ExpandoObjectを参考にさせて頂きます。
    ありがとうございます。

    質問時のサンプルプログラムは構文エラーが多く申し訳ありません。

    public class Dai
    {
    public syou_A = new syouA();

    public syou_B {get; set;}

    public Dai()
    {
    this.syou_B = new syouB();
    }
    }

    public class syouA
    {
    public string nameA = string.Empty;
    public object ageA = 0;
    }

    public class syouB
    {
    public string nameB { get; set;}
    public object ageB { get; set;}

    public syouB()
    {
    nameB = string.Empty;
    ageB = 0;
    }
    }

    public class Test
    {
    private dai = new Dai();

    public Test()
    {
    dai = new Dai();

    dai.syou_A.nameA = "なまえ";
    dai.syou_A.ageA = "99";

    dai.syou_B.nameB = "ナマエ";
    dai.syou_B.ageB = "0";
    }

    public void doutekiniSyutoku()
    {
    string getname = "Dai"."syou_A"."nameA";
    }
    }
解決み!
違反を報告
引用返信 削除キー/



トピック内ページ移動 / << 0 >>

このトピックに書きこむ

Mode/  Pass/


- Child Tree -