C#高级:通过一个遍历实体的小案例去理解反射(基础版)

目录

一、获取字段名+字段类型+字段值+设置字段的值

【实现的demo】

【方法封装-获取一个实体的字段列表】

二、创建实例并且赋值 

三、反射的意义

四、继承对反射的作用

五、实际应用1:让日志输出更多信息(反射打印一个实体的所有字段所有内容)

六、实际应用2:EF的映射Map方法(转移相同字段的数据)

七、实际应用3:使用Invoke关键字通过 Type 类型调用指定的方法


一、获取字段名+字段类型+字段值+设置字段的值

        反射,就是遍历实体的PropertyInfo,获取实体的字段的值、特性、类型

【实现的demo】

class Program
{
    public class Student
    {
        public int id { get; set; }
        public string name { get; set; }

        public int age { get; set; }
    }

    /// <summary>
    /// 通过反射设置实体的值
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    private static void SetValueByReflect<T>(T entity, string feildName, object feildValue) where T : class
    {
        var feild = typeof(T).GetProperty(feildName);
        var feildType = feild?.PropertyType;
        if (feild != null && feildType != null)
        {
            var valueToSet = Convert.ChangeType(feildValue, feildType);//输入的值类型转化为实体属性的类型
            feild.SetValue(entity, valueToSet);
        }
    }

    static void Main()
    {
        Student stu = new Student { id = 1, name = "小苏", age = 18 };

        //任务一:遍历打印这个实体的字段名,字段类型,字段的值
        var propertyList = typeof(Student).GetProperties();
        foreach (var fields in propertyList)
        {
            Console.Write($"字段名: {fields.Name}, ");

            Console.Write($"字段类型: {fields.PropertyType.Name}, 字段类型是否为int: {fields.PropertyType == typeof(int)},");

            Console.WriteLine($"字段在传入实体stu中对应的值: {fields.GetValue(stu)}");
        }

        //任务二:获取传入实体stu的age字段,将其age字段值设置为20
        SetValueByReflect(stu, "age", 20);
        Console.WriteLine($"修改后的age字段值是:{stu.age}");
    }
}

输出效果:

字段名: id, 字段类型: Int32, 字段类型是否为int: True,字段在传入实体stu中对应的值: 1
字段名: name, 字段类型: String, 字段类型是否为int: False,字段在传入实体stu中对应的值: 小苏
字段名: age, 字段类型: Int32, 字段类型是否为int: True,字段在传入实体stu中对应的值: 18
修改后的age字段值:20,即20

【方法封装-通过反射设置实体的值】

/// <summary>
/// 通过反射设置实体的值
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
private static void SetValueByReflect<T>(T entity, string feildName, object feildValue) where T : class
{
    var feild = typeof(T).GetProperty(feildName);
    var feildType = feild?.PropertyType;
    if (feild != null && feildType != null)
    {
        var valueToSet = Convert.ChangeType(feildValue, feildType);//输入的值类型转化为实体属性的类型
        feild.SetValue(entity, valueToSet);
    }
}

二、创建实例并且赋值 

Type type = typeof(T);// 获取泛型类型T的Type对象,便于后面使用

string propertyName = "Name";//要修改的属性名称 例如 Name

var csType = type.GetProperty(propertyName).PropertyType;//获取 Name 的属性,例如 string

object instance = Activator.CreateInstance(type);//创建实例,类似于 T instance = new T()

type.GetProperty(propertyName)?.SetValue(instance, Convert.ChangeType("Hello, World!", csType))//赋值,类似于 instance.Name = "Hello, World!".ToString()   ChangeType是确保其他类型也可以转化成功

创建实例想调用某个类的方法需要强制转化(例转化为Form类):

form = (Form)Activator.CreateInstance(type); 
form.Show(); 

三、反射的意义

【反射获取字段的意义】灵活获取/设置指定字段的值

四、继承对反射的作用

 ABP框架中,一个实体继承Entity对于反射的有什么好处?

public class Entity : Entity<int>
{
    [Required]
    [Column("id")]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public override int Id { get; protected set; }
}

        好处在于:封装反射方法(例如入参 T)可以写成

where T : Entity

        相当于说明了T的实体拥有int id字段,后面可以直接使用这个id字段,而不需要通过反射获取(如果where T : class,想访问id字段还需要其他判断)。

五、实际应用1:让日志输出更多信息(反射打印一个实体的所有字段所有内容)

可访问我另一篇笔记

六、实际应用2:EF的映射Map方法(转移相同字段的数据)

可访问我另一篇笔记

七、实际应用3:使用Invoke关键字通过 Type 类型调用指定的方法

C#高级:使用Invoke关键字通过 Type 类型调用指定的方法-优快云博客

八、实际应用4:通过反射判断列表中指定字段是否存在空值

C#高级:通过反射判断列表中指定字段是否存在空值-优快云博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值