Last active
January 5, 2017 14:27
-
-
Save nexpr/175ba9cf7aa48e45dba22247222b72c4 to your computer and use it in GitHub Desktop.
reflection helper
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| namespace samproj | |
| { | |
| public class Class1 | |
| { | |
| private int _num = 5; | |
| public int num | |
| { | |
| get { return this._num; } | |
| set | |
| { | |
| this._num = value; | |
| this.str += value; | |
| } | |
| } | |
| private string str { get; set; } | |
| protected bool flag = true; | |
| public Class1(string str) | |
| { | |
| this.str = str; | |
| } | |
| public class T1 { | |
| private static T2 make() | |
| { | |
| return new T2(); | |
| } | |
| } | |
| private class T2 | |
| { | |
| private int val = 0; | |
| public void set(int a) | |
| { | |
| this.val = a; | |
| } | |
| private void set() | |
| { | |
| this.val = 0; | |
| } | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| var type = Type.GetType("samproj.Class1, samproj"); | |
| var inst = type.create(new object[] { "abcd" }); | |
| var num = inst.get("num"); | |
| // 5 | |
| var _num = inst.getPrivate("_num"); | |
| // 5 | |
| var str = inst.getPrivate("str"); | |
| // abcd | |
| var flag = inst.getPrivate("flag"); | |
| // true | |
| inst.set("num", 20); | |
| inst.setPrivate("_num", 30); | |
| inst.setPrivate("flag", false); | |
| var num2 = inst.get("num"); | |
| // 30 | |
| var _num2 = inst.getPrivate("_num"); | |
| // 30 | |
| var str2 = inst.getPrivate("str"); | |
| // abcd20 | |
| var flag2 = inst.getPrivate("flag"); | |
| // false | |
| var t1 = type.getInnerType("T1"); | |
| var t2ig = t1.invokePrivate("make", null); | |
| // T2 {} | |
| var t2 = type.getInnerType("T2"); | |
| var t2i = t2.create(null); | |
| t2i.invokePrivate("set", new object[] { 100 }); | |
| var val = t2i.getPrivate("val"); | |
| // 100 | |
| t2i.invokePrivate("set", null); | |
| var val2 = t2i.getPrivate("val"); | |
| // 0 | |
| // T2 is private, but set method is public. | |
| t2i.invoke("set", new object[] { 200 }); | |
| // xxxPrivate method can access public and non-public. | |
| var num_o = inst.getPrivate("num"); | |
| // Exception: flag is non-public field. | |
| var flag_x = inst.get("flag"); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System; | |
| using System.Reflection; | |
| namespace liblib | |
| { | |
| public static class ReflectionExtension | |
| { | |
| /// <summary> | |
| /// ReflectionExtension でのエラー | |
| /// </summary> | |
| public class RuntimeReflectionException : Exception | |
| { | |
| public RuntimeReflectionException(string message) : base(message) { } | |
| } | |
| /// <summary> | |
| /// リフレクションでプロパティ/フィールドを取得 | |
| /// </summary> | |
| /// <param name="obj"></param> | |
| /// <param name="name"></param> | |
| /// <param name="instance"></param> | |
| /// <param name="only_public"></param> | |
| /// <returns></returns> | |
| public static object getCommon(Type type, string name, object instance, bool only_public) | |
| { | |
| var flags = BindingFlags.GetProperty | BindingFlags.GetField | BindingFlags.Public | |
| | (instance == null ? BindingFlags.Static : BindingFlags.Instance) | |
| | (only_public ? 0 : BindingFlags.NonPublic); | |
| var pinfo = type.GetProperty(name, flags); | |
| if (pinfo != null) | |
| { | |
| return pinfo.GetValue(instance); | |
| } | |
| var finfo = type.GetField(name, flags); | |
| if (finfo != null) | |
| { | |
| return finfo.GetValue(instance); | |
| } | |
| throw new RuntimeReflectionException($"'{name}' field or property not found."); | |
| } | |
| public static object get(this object obj, string name) | |
| { | |
| return getCommon(obj.GetType(), name, obj, true); | |
| } | |
| public static object getPrivate(this object obj, string name) | |
| { | |
| return getCommon(obj.GetType(), name, obj, false); | |
| } | |
| public static object get(this Type type, string name) | |
| { | |
| return getCommon(type, name, null, true); | |
| } | |
| public static object getPrivate(this Type type, string name) | |
| { | |
| return getCommon(type, name, null, false); | |
| } | |
| /// <summary> | |
| /// リフレクションでプロパティ/フィールドを設定 | |
| /// </summary> | |
| /// <param name="type"></param> | |
| /// <param name="name"></param> | |
| /// <param name="instance"></param> | |
| /// <param name="value"></param> | |
| /// <param name="only_public"></param> | |
| public static void setCommon(Type type, string name, object instance, object value, bool only_public) | |
| { | |
| var flags = BindingFlags.GetProperty | BindingFlags.GetField | BindingFlags.Public | |
| | (instance == null ? BindingFlags.Static : BindingFlags.Instance) | |
| | (only_public ? 0 : BindingFlags.NonPublic); | |
| var pinfo = type.GetProperty(name, flags); | |
| if (pinfo != null) | |
| { | |
| pinfo.SetValue(instance, value); | |
| return; | |
| } | |
| var finfo = type.GetField(name, flags); | |
| if (finfo != null) | |
| { | |
| finfo.SetValue(instance, value); | |
| return; | |
| } | |
| throw new RuntimeReflectionException($"'{name}' field or property not found."); | |
| } | |
| public static void set(this object obj, string name, object value) | |
| { | |
| setCommon(obj.GetType(), name, obj, value, true); | |
| } | |
| public static void setPrivate(this object obj, string name, object value) | |
| { | |
| setCommon(obj.GetType(), name, obj, value, false); | |
| } | |
| public static void set(this Type type, string name, object value) | |
| { | |
| setCommon(type, name, null, value, true); | |
| } | |
| public static void setPrivate(this Type type, string name, object value) | |
| { | |
| setCommon(type, name, null, value, false); | |
| } | |
| /// <summary> | |
| /// リフレクションでメソッド実行 | |
| /// </summary> | |
| /// <param name="type"></param> | |
| /// <param name="name"></param> | |
| /// <param name="instance"></param> | |
| /// <param name="args"></param> | |
| /// <param name="only_public"></param> | |
| /// <returns></returns> | |
| public static object invokeCommon(Type type, string name, object instance, object[] args, bool only_public) | |
| { | |
| var flags = BindingFlags.InvokeMethod | BindingFlags.Public | |
| | (instance == null ? BindingFlags.Static : BindingFlags.Instance) | |
| | (only_public ? 0 : BindingFlags.NonPublic); | |
| return type.InvokeMember(name, flags, null, instance, args); | |
| } | |
| public static object invoke(this object obj, string name, object[] args) | |
| { | |
| return invokeCommon(obj.GetType(), name, obj, args, true); | |
| } | |
| public static object invokePrivate(this object obj, string name, object[] args) | |
| { | |
| return invokeCommon(obj.GetType(), name, obj, args, false); | |
| } | |
| public static object invoke(this Type type, string name, object[] args) | |
| { | |
| return invokeCommon(type, name, null, args, true); | |
| } | |
| public static object invokePrivate(this Type type, string name, object[] args) | |
| { | |
| return invokeCommon(type, name, null, args, false); | |
| } | |
| public static object create(this Type type, object[] args) | |
| { | |
| return Activator.CreateInstance(type, args); | |
| } | |
| public static Type getInnerType(this Type type, string name) | |
| { | |
| var flags = BindingFlags.Public | BindingFlags.NonPublic; | |
| return type.GetNestedType(name, flags); | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment