C#基础之反射

这篇博客探讨了C#中的反射概念,包括它的定义和用途。文章详细阐述了如何使用反射来访问字段、属性和方法,并进一步讨论了如何借助反射实现动态功能更新。

快速定义:什么是反射?反射能用来做什么?

	动态调用方法;
	动态调用对象;
	从程序集中直接获取类;
	更新程序;

以下为反射的一些实现:

	首先,我们有一个student类
class student 
    {
        public int id { get; set; }
        public string name { get; set; }
        public int age;
        public void Show() 
        {
            Console.WriteLine("this is show");
        }

        public string Show2(string name)
        {
            return $"你好,{name}";
        }

    }
	而后,我们创建一个object对象
object obj = new student();
Type type = obj.GetType();
	如何访问到刚刚创建的obj中的字段,属性,以及方法?

1.访问字段

 //GetFields() 获取所有公开的字段
 //GetField(string fieldName) 获取特定名称字段
 type.GetField("age").SetValue(obj, 25);
 Console.WriteLine(type.GetField("age").GetValue(obj));
 //可以使用foreach来访问到所有字段,并在foreach中判断字段
    需要注意的事情是,使用Type类型的方法GetType(),获取到的是该类的所有属性,但是只是所有属性
而已,并没有和对象obj有联系,所以在后面的GetField("age").SetValue(obj, 25);中,还需要写入obj
以此来确认需要Get或SetValue的对象是谁。

2.访问属性

//GetProperties() 获取所有公开属性
//GetProperty() 获取特定名称属性
type.GetProperty("id").SetValue(obj,55);
type.GetProperty("name").SetValue(obj, "hello");

3.访问方法

//GetMethods() 获取所有公开的方法
//GetMethod() 获取特定名称方法
var show = type.GetMethod("Show");
show.Invoke(obj, new object[0]);
var show2 = type.GetMethod("Show2");
object name = show2.Invoke(obj,new object[] {"张三" });
    Invoke属性的第二个参数,如果没有形参,传入一个 object[0]即可,如果有形参,object内填写形参
因为object是所有类的父类,所以无论传什么进去都可以,返回的参数也需要用object类来接收,此
时,可以使用 is 来判断返回的参数类型,也可强制转换
if (name is string)
{
  Console.WriteLine("是string");
  string result = (string)name;
}

反射的实现2:

如何利用反射的原理来实现更新功能?
先有一个类:

namespace StudentManager.UserManager
{
    public class User
    {
        public string Name { get; set; }
        public int Age { get; set; }
        private void Game()
        {
            Console.WriteLine($"{Name}正在玩游戏");
        }
        public void SayHi()
        {
            Console.WriteLine($"你好,我是{Name},今年{Age}岁了");
            Game();
        }
    }
}
    不利用引用的情况下,将此类生成的dll复制到需要用到此类的程序的文件夹中,利用
Environment.CurrentDirectory来确定绝对路径。
Assembly ass = Assembly.LoadFile(Environment.CurrentDirectory + @"\libs\ClassLibrary2.dll");
//绝对路径后加上dll文件名
var user = ass.GetTypes().First(m => !m.IsInterface && m.IsClass);
//这里使用First方法获取第一个类
//    Console.WriteLine(type.IsClass);
//    Console.WriteLine(type.IsInterface);
//    Console.WriteLine(type.IsEnum);
//    Console.WriteLine(type.IsAbstract);
//可以使用一些判断来判断type类型
object obj = ass.CreateInstance(user.FullName);
user.GetProperty("Age").SetValue(obj, 25);
user.GetProperty("Name").SetValue(obj, "张三");
Console.WriteLine(user.GetProperty("Age").GetValue(obj));
user.GetMethod("SayHi").Invoke(obj,new object[0]);
//以上是如何动态创建一个对象,并修改属性,字段,使用方法
//需要引用的程序集:
//using System.Linq;
//using System.Reflection;
    至此,如果更新了这个类,只需要把新的dll复制到需要用到此类程序的文件夹中即可,实现
更新程序,需注意的是,在解决方案导航中,需要把该文件的【复制到输出目录】属性更改为:
如果较新则复制

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值