読者です 読者をやめる 読者になる 読者になる

RunningCSharp

.net中心の開発話。記事は個人の見解であり、所属組織を代表するものてはありません。

C#:基底クラスのプロパティ情報をリフレクションで取得する拡張メソッド

    /// <summary>
    /// 基底クラス
    /// </summary>
    public class SuperClass
    {
        public SuperClass()
        {
            SuperProperty = "Super";
        }
        private string SuperProperty { get; set; }
    }

    /// <summary>
    /// 派生クラス(子クラス)
    /// </summary>
    public class Sub1Class : SuperClass
    {
    }

    /// <summary>
    /// 派生クラスの派生クラス(孫クラス)
    /// </summary>
    public class Sub2Class : Sub1Class
    {
    }

上記のようなクラス構成で「Sub2Class」より、SuperClassのSuperPropertyを取得したい場合、 privateなプロパティなので、リフレクションを用いて取得することになります。

しかし、孫クラスとなっているため単純にBaseTypeでクラス情報を取得することもできないため、 プロパティ名とBindingFlagsを渡すと継承ツリーからプロパティを取得してくる拡張メソッドを作成してみました。

    public static class MethodClass
    {
        /// <summary>
        /// プロパティ名とBindingFlagsより、型の継承ツリー内にあるプロパティ情報を検索し返却します。
        /// 最も派生クラスに近いクラスのプロパティが返却されます。
        /// </summary>
        /// <param name="type"></param>
        /// <param name="name">プロパティ名</param>
        /// <param name="bindingAttr">BindingFlags</param>
        /// <returns>プロパティを表すオブジェクト</returns>
        public static PropertyInfo GetSuperClassPropertyInfo(this Type type, string name, BindingFlags bindingAttr)
        {
            var info = type.GetProperty(name, bindingAttr);
            if (info != null)
            {
                return info;
            }
            else if (type.BaseType != null)
            {
                return type.BaseType.GetSuperClassPropertyInfo(name, bindingAttr);
            }
            return null;
        }
    }

下記のような形で使用します。

    class Program
    {
        static void Main(string[] args)
        {
            Sub2Class sub2Class = new Sub2Class();
            var info = sub2Class.GetType().GetSuperClassPropertyInfo("SuperProperty", BindingFlags.Instance | BindingFlags.NonPublic);
            Console.WriteLine((string)info.GetValue(sub2Class));
            Console.ReadLine();
        }
    }

実行結果は、

Super

となります。

もう少しスマートな方法があると良いなとは思うのですが…