反射获取类的属性和对象的属性值

时间:2021-10-28 05:15:43
public Dictionary<string, string> GetDict<T>(T obj,params string[] exclusive)
        {
            Dictionary<string, string> dict = new Dictionary<string, string>();
            Type t = typeof(T);
            foreach (var info in t.GetProperties())
            {
                if (exclusive.Contains(info.Name)) continue;
                dict[info.Name]=info.GetValue(obj).ToString();
            }
            return dict;
        }

 反射调用机制:

反射获取类的属性和对象的属性值反射获取类的属性和对象的属性值
class Program
    {
        static void Main(string[] args)
        {
            Type t = typeof(SomeType);
            BindToMemberThenInvokeTheMember(t);
            Console.WriteLine();

            BindToMemberCreateDelegateToMenberThenInvokeTheMember(t);
            Console.WriteLine();

            UseDynamicToBindAndInvokeTheMember(t);
            Console.WriteLine();

            Console.ReadKey();
        }

        private static void UseDynamicToBindAndInvokeTheMember(Type t)
        {
            Console.WriteLine("UseDynamicToBindAndInvokeTheMember");
            object[] args = new object[] { 12 };
            Console.WriteLine("x before constructor called: " + args[0]);
            dynamic obj = Activator.CreateInstance(t, args);
            Console.WriteLine("Type: " + obj.GetType());
            Console.WriteLine("x after constructor returns: " + args[0]);

            try
            {
                obj.m_someField = 5;
                int v = (int)obj.m_someField;
                Console.WriteLine("someField: " + v);
            }
            catch (RuntimeBinderException e)
            {
                Console.WriteLine("Failed to access field: " + e.Message);
            }

            string s = (string)obj.ToString();
            Console.WriteLine("ToString: " + s);
            try
            {
                obj.SomeProp = 0;
            }
            catch (ArgumentOutOfRangeException)
            {
                Console.WriteLine("Property set catch.");
            }
            obj.SomeProp = 2;
            int val = (int)obj.SomeProp;
            Console.WriteLine("SomeProp: " + val);

            obj.SomeEvent += new EventHandler(EventCallback);
            obj.SomeEvent -= new EventHandler(EventCallback);
        }

        private static void BindToMemberCreateDelegateToMenberThenInvokeTheMember(Type t)
        {
            Console.WriteLine("BindToMemberCreateDelegateToMenberThenInvokeTheMember");
            object[] args = new object[] { 12 };
            Console.WriteLine("x before constructor called: " + args[0]);
            object obj = Activator.CreateInstance(t, args);
            Console.WriteLine("Type: " + obj.GetType());
            Console.WriteLine("x after constructor returns: " + args[0]);

            MethodInfo mi = obj.GetType().GetTypeInfo().GetDeclaredMethod("ToString");
            var toString = mi.CreateDelegate<Func<String>>(obj);
            string s = toString();
            Console.WriteLine("ToString: " + s);

            PropertyInfo pi = obj.GetType().GetTypeInfo().GetDeclaredProperty("SomeProp");
            var setSomeProp = pi.SetMethod.CreateDelegate<Action<Int32>>(obj);
            try
            {
                setSomeProp(0);
            }
            catch (ArgumentOutOfRangeException)
            {
                Console.WriteLine("Property set catch.");
            }
            setSomeProp(2);
            var getSomeProp = pi.GetMethod.CreateDelegate<Func<int>>(obj);
            Console.WriteLine("SomeProp: " + getSomeProp());

            EventInfo ei = obj.GetType().GetTypeInfo().GetDeclaredEvent("SomeEvent");
            var addSomeEvent = ei.AddMethod.CreateDelegate<Action<EventHandler>>(obj);
            addSomeEvent(EventCallback);
            var removerSomeEvent = ei.RemoveMethod.CreateDelegate<Action<EventHandler>>(obj);
            removerSomeEvent(EventCallback);
        }

        private static void BindToMemberThenInvokeTheMember(Type t)
        {
            Console.WriteLine("BindToMemberThenInvokeTheMember");
            Type ctorArgument = Type.GetType("System.Int32&");
            ConstructorInfo ctor = t.GetTypeInfo().DeclaredConstructors.First(x => x.GetParameters()[0].ParameterType == ctorArgument);
            object[] args = new object[] { 12 };
            Console.WriteLine("x before constructor called: " + args[0]);
            object obj = ctor.Invoke(args);
            Console.WriteLine("Type: " + obj.GetType());
            Console.WriteLine("x after constructor returns: " + args[0]);

            FieldInfo fi = obj.GetType().GetTypeInfo().GetDeclaredField("m_someField");
            fi.SetValue(obj, 33);
            Console.WriteLine("someField: " + fi.GetValue(obj));

            MethodInfo mi = obj.GetType().GetTypeInfo().GetDeclaredMethod("ToString");
            string s = (string)mi.Invoke(obj, null);
            Console.WriteLine("ToString: " + s);

            PropertyInfo pi = obj.GetType().GetTypeInfo().GetDeclaredProperty("SomeProp");
            try
            {
                pi.SetValue(obj, 0, null);
            }
            catch (TargetInvocationException e)
            {
                if (e.InnerException.GetType() != typeof(ArgumentOutOfRangeException)) /*throw;*/
                Console.WriteLine("Property set catch.");
            }
            pi.SetValue(obj, 2, null);
            Console.WriteLine("SomeProp: " + pi.GetValue(obj, null));

            EventInfo ei = obj.GetType().GetTypeInfo().GetDeclaredEvent("SomeEvent");
            EventHandler eh = new EventHandler(EventCallback);
            ei.AddEventHandler(obj, eh);
            ei.RemoveEventHandler(obj, eh);
        }

        private static void EventCallback(object sender, EventArgs e)
        {
            
        }
    }

    internal sealed class SomeType
    {
        private int m_someField;
        public SomeType(ref int x)
        {
            x *= 2;
        }
        public override string ToString()
        {
            return m_someField.ToString();
        }
        public int SomeProp
        {
            get { return m_someField; }
            set
            {
                if (value < 1)
                    throw new ArgumentOutOfRangeException("value");
                m_someField = value;
            }
        }
        public event EventHandler SomeEvent;
        private void NoCompilerWarnings()
        {
            SomeEvent.ToString();
        }
    }

    internal static class ReflectionExtensions
    {
        public static TDelegate CreateDelegate<TDelegate>(this MethodInfo mi,object target=null)
        {
            return (TDelegate)(object)mi.CreateDelegate(typeof(TDelegate), target);
        }
    }
View Code