50586


お世話になります。  
C#のobject型から値を取得したいと思っております。以下のコードからhoge2の値である「"2"」を取得するにはどうしたら良いでしょうか？ご教授お願いします。

[code]

    object obj = new { hoge = 1, hoge2 = "2"};
    
[/code]


CC BY-SA 4.0
2018-11-23T16:47:24.400
50577
2018-11-24T06:28:16.050
24385
question
c#
キーバリューになっているobject型から値を取得する方法について


動的型付け変数を使えば可能です。

[code]

    object obj = new { hoge = 1, hoge2 = "2" };
    
    dynamic d = obj;
    Console.WriteLine(d.hoge2);
    
[/code]

ただし動的型付け変数を多用すると静的型付け言語であるC#のメリットをがなくなり、  
動的型付けのデメリットが発生します。  
結果、静的型付けのデメリットと動的型付けのデメリットの両方があるひどいプログラムになってしまいます。


CC BY-SA 4.0
2018-11-24T02:25:18.087
50580
2018-11-24T02:25:18.087
18616
50577
answer


ちょっと大変ですが、 [GetValue(Object)](https://docs.microsoft.com/ja-
jp/dotnet/api/system.reflection.propertyinfo.getvalue?view=netframework-4.7.2#System_Reflection_PropertyInfo_GetValue_System_Object_)
と [動的にGetType()で得られる型に変換するには](http://d.hatena.ne.jp/tueda_wolf/20141211/p1)
の組み合わせで、こんな風にキー名を指定して型と値が取得できます。  
まあ、もっと簡潔なやり方はあるのでしょうけれど。  
あとここでは、バリューが配列とか複合型の場合については省略です。

[code]

    using System;
    using System.Reflection;
    
    namespace ConsoleApp1
    {
        class Program
        {
            static void Main(string[] args)
            {
                object obj = new { hoge = 1, hoge2 = "2" };
    
                string key = "hoge2";
                object value = GetValueByKeyName(obj, key);
                if (value != null)
                {
                    Type t = value.GetType();
                    var v = Convert.ChangeType(value, t);
                    Console.WriteLine("{0} type is: {1}, value is: {2}", key, t.Name, v.ToString());
                }
                else
                {
                    Console.WriteLine("{0} does not exist", key);
                }
                return;
            }
    
            private static object GetValueByKeyName(object obj, string name)
            {
                object result = null;
                Type t = obj.GetType();
                PropertyInfo[] props = t.GetProperties();
                foreach (var prop in props)
                {
                    if (prop.GetIndexParameters().Length == 0)
                    {
                        if (prop.Name.Equals(name))
                        {
                            result = prop.GetValue(obj);
                            break;
                        }
                    }
                }
                return result;
            }
        }
    }
    
[/code]


CC BY-SA 4.0
2018-11-24T06:22:57.640
50586
2018-11-24T06:28:16.050
2018-11-24T06:28:16.050
26370
26370
50577
answer