目录
五、实际应用1:让日志输出更多信息(反射打印一个实体的所有字段所有内容)
一、获取字段名+字段类型+字段值
Student stu = new Student { id = 1, name = "小苏", age = 18 };
//任务一:遍历打印这个实体的字段名,字段类型,字段的值
foreach (var fields in GetEntity<Student>())
{
Console.Write($"字段名: {fields.Name}, ");
Console.Write($"字段类型: {fields.PropertyType.Name}, 字段类型是否为int: {fields.PropertyType==typeof(int)},");
Console.WriteLine($"字段在传入实体stu中对应的值: {fields.GetValue(stu)}");
}
二、设置字段的值
//任务二:获取传入实体stu的age字段,将其age字段值设置为20
var age_field = GetEntity<Student>("age").FirstOrDefault();
age_field?.SetValue(stu, 20);
Console.WriteLine($"修改后的age字段值:{stu.age},即{age_field?.GetValue(stu)}");
【实现的demo】
using ConsoleApp1;
using SqlSugar;
using System.DirectoryServices.ActiveDirectory;
using System.Reflection;
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>
static PropertyInfo[] GetEntity<T>(string Fieldname = "") where T : class
{
if(!string.IsNullOrEmpty(Fieldname))
{
return typeof(T).GetProperties().Where(x => x.Name == Fieldname).ToArray();
}
return typeof(T).GetProperties();
}
static void Main()
{
Student stu = new Student { id = 1, name = "小苏", age = 18 };
//任务一:遍历打印这个实体的字段名,字段类型,字段的值
foreach (var fields in GetEntity<Student>())
{
Console.Write($"字段名: {fields.Name}, ");
Console.Write($"字段类型: {fields.PropertyType.Name}, 字段类型是否为int: {fields.PropertyType==typeof(int)},");
Console.WriteLine($"字段在传入实体stu中对应的值: {fields.GetValue(stu)}");
}
//任务二:获取传入实体stu的age字段,将其age字段值设置为20
var age_field = GetEntity<Student>("age").FirstOrDefault();
age_field?.SetValue(stu, 20);
Console.WriteLine($"修改后的age字段值:{stu.age},即{age_field?.GetValue(stu)}");
}
}
输出效果:
字段名: 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>
static PropertyInfo[] GetEntity<T>(string Fieldname = "") where T : class
{
if(!string.IsNullOrEmpty(Fieldname))
{
return typeof(T).GetProperties().Where(x => x.Name == Fieldname).ToArray();
}
return typeof(T).GetProperties();
}
三、反射的意义
【反射获取字段的意义】灵活获取/设置指定字段的值
四、继承对反射的作用
ABP框架中,一个实体继承DOEntity对于反射的有什么好处?
public class DOEntity : DOEntity<int>
{
[Required]
[Column("id")]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public override int Id { get; protected set; }
}
好处在于:封装反射方法(例如入参 T)可以写成
where T : DOEntity
相当于说明了T的实体拥有int id字段,后面可以直接使用这个id字段,而不需要通过反射获取(如果where T : class,想访问id字段还需要其他判断)。