C#反射案例

  学习来源:《CLR via C by Jeffrey Richter 》第四版,第23章  程序集加载和反射

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Microsoft.CSharp.RuntimeBinder;
using System.Text;
using System.Threading.Tasks;

namespace 反射案例
{
    class Program
    {
        static void Main(string[] args)
        {
            Type type = typeof(SomeType);
            BindToMemberThenInvokeTheMember(type);
            BindToMemberCreateDelegateToMember(type);
            UseDynamicToBindAndInvokeTheMemnber(type);
        }
        private static void EventCallback(object sender, EventArgs eventArgs) { }

        /// 
        /// 反射创建实例,用反射实例获取成员,调用/设置成员
        /// 
        /// 
        private static  void  BindToMemberThenInvokeTheMember(Type t)
        {
            Console.WriteLine("BindToMemberThenInvokeTheMember");
            Type ctorArgument = Type.GetType("System.Int32&");
            //构造实例
            ConstructorInfo constructor = t.GetTypeInfo().DeclaredConstructors.First(c => c.GetParameters()[0].ParameterType == ctorArgument);
            object[] args = new object[] { 12 };
            Console.WriteLine("x={0}", args[0]);
            object obj = constructor.Invoke(args);
            Console.WriteLine("实例类型:{0}", obj.GetType());
            Console.WriteLine("x={0}", args[0]);

            //读写字段
            FieldInfo fieldInfo = obj.GetType().GetTypeInfo().GetDeclaredField("m_somefield");
            fieldInfo.SetValue(obj, 33);
            Console.WriteLine("m_somefield=", fieldInfo.GetValue(obj));

            //调用方法
            MethodInfo methodInfo = obj.GetType().GetTypeInfo().GetDeclaredMethod("ToString");
            string s = (string)methodInfo.Invoke(obj, null);
            Console.WriteLine("tostirng:" + s);

            //读写属性
            PropertyInfo propertyInfo = obj.GetType().GetTypeInfo().GetDeclaredProperty("SomeProp");
            try
            {
                propertyInfo.SetValue(obj, 0, null);
            }
            catch (TargetInvocationException e)
            {
                if (e.InnerException.GetType() == typeof(ArgumentOutOfRangeException)) { throw; }
                Console.WriteLine("属性设置异常");
            }

            //事件添加/删除委托
            EventInfo eventInfo = obj.GetType().GetTypeInfo().GetDeclaredEvent("SomeEvent");
            EventHandler eventHandler = new EventHandler(EventCallback);
            eventInfo.AddEventHandler(obj, eventHandler);
            eventInfo.RemoveEventHandler(obj, eventHandler);
        }
        /// 
        /// 反射创建实例,用实例的获取成员,用成员的委托调用方法,属性,事件
        /// 
        /// 
        private static void BindToMemberCreateDelegateToMember(Type type) {
            Console.WriteLine("BindToMemberCreateDelegateToMember");
            //构造实例
            object[] args = new object []{ 12 };//实例参数
            Console.WriteLine("x={0}",args[0]);
            object obj = Activator.CreateInstance(type, args);
            Console.WriteLine("实例类型={0}",obj.GetType().ToString());
            Console.WriteLine("x={0}",args[0]);
            //注意不能创建对字段的委托

            //调用方法
            MethodInfo methodInfo = obj.GetType().GetTypeInfo().GetDeclaredMethod("ToString");
            //  var setSomeProp = methodInfo.CreateDelegateFunc(obj);
            //string s = tostring();
            //Console.WriteLine(s);

            //属性
            PropertyInfo propertyInfo = obj.GetType().GetTypeInfo().GetDeclaredProperty("SomeProp");
            var setSomeProp = propertyInfo.SetMethod.CreateDelegate>(obj);
            try
            {
                setSomeProp(0);
            }
            catch (ArgumentOutOfRangeException e)
            {

                Console.WriteLine("BindToMemberCreateDelegateToMember setSomeProp error");
            }
            setSomeProp(2);
            var getSomeProp = propertyInfo.SetMethod.CreateDelegate>(obj);
            Console.WriteLine(getSomeProp());


            //事件
            EventInfo eventInfo = obj.GetType().GetTypeInfo().GetDeclaredEvent("SomeEvent");
            var addSomeEvent = eventInfo.AddMethod.CreateDelegate>(obj);
            addSomeEvent(EventCallback);
            var removeSomeEvent = eventInfo.RemoveMethod.CreateDelegate>(obj);
            removeSomeEvent(EventCallback);
        }

        /// 
        /// 反射创建实例,用Dynamic接收,调用/设置成员
        /// 
        /// 
        private static void UseDynamicToBindAndInvokeTheMemnber(Type type) {
            Console.WriteLine("UseDynamicToBindAndInvokeTheMemnber");
            //构造实例
            object[] args = new object[] { 12 };//参数
            dynamic obj = Activator.CreateInstance(type, args);
            Console.WriteLine("实例类型={0}", obj.GetType().ToString());
            Console.WriteLine("x={0}", args[0]);
            try
            {
                obj.m_somefield = 5;
                int v = (Int32)obj.m_somefield;
                Console.WriteLine("m_somefield=" + v.ToString());
            }
            catch (RuntimeBinderException e)
            {
                Console.WriteLine("dynamic m_somefield error");
            }
            string s = (string)obj.ToString();
            Console.WriteLine(s);
            try
            {
                obj.SomeProp = 0;
            }
            catch (ArgumentOutOfRangeException e)
            {
                Console.WriteLine("dynamic SomeProp error");
            }
            obj.SomeProp = 2;
            int val = (Int32)obj.SomeProp;
            Console.WriteLine("SomeProp="+val);
            obj.SomeEvent += new EventHandler(EventCallback);
            obj.SomeEvent -= new EventHandler(EventCallback);

        }

    }
    internal static class ReflectionExtensions {
        public static T CreateDelegate(this MethodInfo methodInfo, object target = null) {
            return (T)(object)methodInfo.CreateDelegate(typeof(T), target);
        }
    }

    public 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;
        public void NoCompilerWanrings() { SomeEvent.ToString(); }
    }

   
}

你可能感兴趣的:(c#)