shuhelohelo’s blog

Xamarin.Forms多めです.

C#で文字列でプロパティにアクセス

qiita.com

インデックスでアクセスする方法が便利そう。リフレクション。

早速やってみよう。

まずはプロパティをいくつか追加する。

そしてusing System.Reflectionを追加する。わかりやすいように初期値も入れておく。

using System.Reflection;

namespace AccessPropertyByStringPractice
{
    public class MyClass
    {
        public int MyProperty1 { get; }
        public int MyProperty2 { get; }
        public int MyProperty3 { get; }

        public MyClass()
        {
            MyProperty1 = 10;
            MyProperty2 = 20;
            MyProperty3 = 30;
        }
    }
}

この3つのプロパティに外部からプロパティ名の文字列で連想配列のようにアクセスできるようにする。

目標イメージ↓

var val = myClass["MyProperty1"];

インデクサの定義をするわけですが、それについては以下のサイトを参照。

ufcpp.net

以下のようにする。

using System.Reflection;

namespace AccessPropertyByStringPractice
{
    public class MyClass
    {
        public int MyProperty1 { get; }
        public int MyProperty2 { get; }
        public int MyProperty3 { get; }

        public MyClass()
        {
            MyProperty1 = 10;
            MyProperty2 = 20;
            MyProperty3 = 30;
        }

        //インデクサの定義
        public object this[string propertyName]
        {
            get
            {
                return typeof(MyClass).GetProperty(propertyName).GetValue(this);
            }
            set
            {
                typeof(MyClass).GetProperty(propertyName).SetValue(this, value);
            }
        }
    }
}

Mainから呼び出してみる。

using System;

namespace AccessPropertyByStringPractice
{
    class Program
    {
        static void Main(string[] args)
        {
            var myClass = new MyClass();

            var val = myClass["MyProperty3"];

            Console.WriteLine($"MyProperty3:{val}");//出力 -> MyProperty3:30
        }
    }
}

上の例ではインデクサの返り値をobjectにしているため、どんな型のプロパティも取得することができるけれど、その代わりに返り値を使用するときは型変換が必要になる。

取得するプロパティの型が1種類に決まっているのであれば、返り値の型を指定すると良いかも。

MyClass側:

///省略

        public int this[string propertyName]
        {
            get
            {
                return (int)typeof(MyClass).GetProperty(propertyName).GetValue(this);
            }
            set
            {
                typeof(MyClass).GetProperty(propertyName).SetValue(this, (int)value);
            }
        }

Main側:

///省略

        static void Main(string[] args)
        {
            var myClass = new MyClass();

            int val = myClass["MyProperty3"];

            Console.WriteLine($"MyProperty3:{val + 100}");//出力 -> MyProperty3:130
        }