C# 反射之成员调用

发布于:2024-09-18 ⋅ 阅读:(55) ⋅ 点赞:(0)
这一篇主要是利用反射来实现对象的实例化以及方法的调用和属性的取值、赋值等。

分别由以下两种方式:

  1. 直接在项目内调用对象;这里就是直接通过Type type = typeof(Form2)来获取Type,当然也可以先实例化再去反射调用,就省去了动态实例化这一步了,如:Type type = new Form2().GetType()
  2. 从dll/exe中加载调用;为了方便,这里是把当前应用生成的exe文件直接复制了一份到输出目录,命名为:copy.exe。

两种方式除了在获取Type的方式不同以外,其他没有什么差别。

以下代码还同时实现了对事件的变更(移除和新增);其实这个还是很好玩的,比如我们可以让一个其他的程序点击按钮的时候去执行我们自己的代码等,可以理解为一个简单的反射注入吧。

实现功能:

- 使用反射动态调用DLL的方法、属性等

开发环境:

开发工具: Visual Studio 2013

.NET Framework版本:4.5

实现代码:

   public partial class Form2 : Form
    {
        public string Value1 { get; set; }

        public string Value2 { get; set; }
        public Form2()
        {
            InitializeComponent();
           
        }
        private void Form2_Load(object sender, EventArgs e)
        {
            label1.Text = Value1;
            Value2 = "New Value";
        }
        public string GetLable1()
        {
           return label1.Text;
        }

        public void SetLable1(string text)
        {
            label1.Text = text;
        }
        public void SetLable2(string text)
        {
            label2.Text = text;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            MessageBox.Show("2222");
        }
    }
    private void btn_form_Click(object sender, EventArgs e)
        {
            Type type = typeof(Form2);
            Invoke(type);
        }

        private void btn_dll_Click(object sender, EventArgs e)
        {
            Assembly assembly = Assembly.LoadFile(Application.StartupPath + "\\copy.exe");
            Type type = assembly.GetType("Reflection.Form2");
            Invoke(type);
        }

        private void Invoke(Type type)
        {
            listBox1.Items.Clear();

            //实例化
            object Instance = Activator.CreateInstance(type, true);

            //给Value1属性赋值
            type.GetProperty("Value1").SetValue(Instance, "Hello");

            //调用Show方法弹出窗口
            type.GetMethod("Show", new Type[0]).Invoke(Instance, null);

            //调用GetLable1获取获取lable1的值
            string lable1 = type.GetMethod("GetLable1").Invoke(Instance, null).ToString();
            listBox1.Items.Add("Lable1的值:" + lable1);

            //获取Value2属性的值
            string value2 = type.GetProperty("Value2").GetValue(Instance, null).ToString();
            listBox1.Items.Add("属性Value2的值:" + value2);

            //调用SetLable2对lable2赋值
            type.GetMethod("SetLable2").Invoke(Instance, new object[] { "你好" });

            //获取button1对象
            FieldInfo fInfo = type.GetField("button1", BindingFlags.NonPublic | BindingFlags.Instance);
            Button btn = fInfo.GetValue(Instance) as Button;

            //移除button1事件
            EventInfo eInfo = btn.GetType().GetEvent("Click");
            FieldInfo btn_fInfo = typeof(Control).GetField("Event" + eInfo.Name, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static);
            PropertyInfo btn_pInfo = btn.GetType().GetProperty("Events",
               BindingFlags.NonPublic | BindingFlags.Instance);

            EventHandlerList list = (EventHandlerList)btn_pInfo.GetValue(btn, null);
            object obj = btn_fInfo.GetValue(btn);
            list.RemoveHandler(obj, list[obj]);

            //给button1添加事件
            btn.Click += new EventHandler((s, e1) =>
            {
                MessageBox.Show("1111");
            });
        }

实现效果:

由简入繁,拿来即用

更多精彩,请持续关注公众号: