本文主要介绍.NET Core(C#)中,使用反射进行类(class)的属性(PropertyInfo)、字段(FieldInfo)和方法(MethodInfo)相关操作,通过扩展方法编写的工具类,以及相关示例代码。

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
namespace CJavaPY.Reflection
{
/// <summary>
/// Utilties for reflection
/// </summary>
public static class ReflectionUtils
{
    /// <summary>
    /// 
    /// DataTable扩展了一个方法,将DataTable中的行转变为对应的class对象,并封装到List集合中;
    /// </summary>
    /// <typeparam name="T">需要转变成为的class类型</typeparam>
    /// <param name="table">传入的DataTable对象</param>
    /// <returns>返回一个封装了对应class的List集合</returns>
    public static List<T> TableToClass<T>(this DataTable table)
    {
        Type type = typeof(T);
        PropertyInfo[] propArr = type.GetProperties(); //获取所有属性
        List<T> list = new List<T>();
        DataRowCollection rows = table.Rows;
        int len = rows[0].ItemArray.Length; //获取第一行的列数,即class的属性个数
        for (int i = 0; i < rows.Count; i++)
        {
            T t = (T) Activator.CreateInstance(type);
            for (int j = 0; j < len; j++) //这里之所以不使用propArr.Length,是因为有些Models的属性在数据表中不存在对应的列
            {
                propArr[j].SetValue(t, rows[i][j]);
            }
            list.Add(t);
            t = default(T);
        }
        return list;
    }
    /// <summary>
    ///
    ///     DataRow的扩展方法;
    ///     将DataRow对象封装到泛型对象中
    /// </summary>
    /// <typeparam name="T">需要转换成为的class类型</typeparam>
    /// <param name="row">被转换的行</param>
    /// <returns>封装了行数据的class对象</returns>
    public static T RowToClass<T>(this DataRow row)
    {
        //Type type = Assembly.Load(classFullName).GetType();
        Type type = typeof(T);
        T t = (T) Activator.CreateInstance(type);
        PropertyInfo[] propArr = type.GetProperties();
        int len = row.ItemArray.Length;
        for (int i = 0; i < len; i++)
        {
            propArr[i].SetValue(t, row[i]);
        }
        return t;
    }
    /// <summary>
    /// 
    ///     DataRowCollection的扩展方法;
    ///     将DataRowCollection对象封装到泛型List集合中
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="rows"></param>
    /// <returns></returns>
    public static List<T> RowToClass<T>(this DataRow row, DataRow[] rowArr)
    {
        Type type = typeof(T);
        PropertyInfo[] propArr = type.GetProperties();
        int len = rowArr[0].ItemArray.Length; //获取数据表第一行的列数,即属性个数
        List<T> list = new List<T>();
        for (int i = 0; i < rowArr.Length; i++)
        {
            T t = (T) Activator.CreateInstance(type);
            for (int j = 0; j < len; j++)
            {
                propArr[j].SetValue(t, rowArr[i][j]);
            }
            list.Add(t);
            t = default(T);
        }
        return list;
    }
    /// <summary>
    /// 获取一个类的所有字段s
    /// </summary>
    /// <param name="type">该类的Type对象</param>
    /// <returns></returns>
    public static IEnumerable<FieldInfo> GetAllFields(this Type type)
    {
        if (type == null)
        {
            return Enumerable.Empty<FieldInfo>();
        }
        BindingFlags flags = BindingFlags.Public |
                             BindingFlags.NonPublic |
                             BindingFlags.Static |
                             BindingFlags.Instance |
                             BindingFlags.DeclaredOnly;
        return type.GetFields(flags).Union(GetAllFields(type.BaseType));
    }
    /// <summary>
    /// 获取类的所有属性
    /// </summary>
    /// <param name="type">该类的Type对象</param>
    /// <returns></returns>
    public static IEnumerable<PropertyInfo> GetAllProperties(this Type type)
    {
        if (type == null)
        {
            return Enumerable.Empty<PropertyInfo>();
        }
        BindingFlags flags = BindingFlags.Public |
                             BindingFlags.NonPublic |
                             BindingFlags.Static |
                             BindingFlags.Instance |
                             BindingFlags.DeclaredOnly;
        return type.GetProperties(flags).Union(GetAllProperties(type.BaseType));
    }
    /// <summary>
    /// 获取类的所有构造函数
    /// </summary>
    /// <param name="type">该类的Type对象</param>
    /// <returns></returns>
    public static IEnumerable<ConstructorInfo> GetAllConstructors(this Type type)
    {
        if (type == null)
        {
            return Enumerable.Empty<ConstructorInfo>();
        }
        BindingFlags flags = BindingFlags.Public |
                             BindingFlags.NonPublic |
                             BindingFlags.Static |
                             BindingFlags.Instance |
                             BindingFlags.DeclaredOnly;
        return type.GetConstructors(flags);
    }
    /// <summary>
    /// 获取类的所有方法
    /// </summary>
    /// <param name="type">该类的Type对象</param>
    /// <returns></returns>
    public static IEnumerable<MethodInfo> GetAllMethods(this Type type)
    {
        if (type == null)
        {
            return Enumerable.Empty<MethodInfo>();
        }
        BindingFlags flags = BindingFlags.Public |
                             BindingFlags.NonPublic |
                             BindingFlags.Static |
                             BindingFlags.Instance |
                             BindingFlags.DeclaredOnly;
        return type.GetMethods(flags).Union(GetAllMethods(type.BaseType));
    }
    public static IEnumerable<string> Keys(this Type type, BindingFlags? propBindingAttr = null,
        BindingFlags? fieldBindingAttr = null)
    {
        List<string> result = new List<string>();
        result.AddRange(PropertyKeys(type, propBindingAttr));
        result.AddRange(FieldKeys(type, fieldBindingAttr));
        return result;
    }
    public static IEnumerable<string> PropertyKeys(this Type type, BindingFlags? bindingAttr = null)
    {
        PropertyInfo[] props = bindingAttr.HasValue ? type.GetProperties(bindingAttr.Value) : type.GetProperties();
        return props.Select(x => x.Name);
    }
    public static IEnumerable<string> FieldKeys(this Type type, BindingFlags? bindingAttr = null)
    {
        FieldInfo[] fields = bindingAttr.HasValue ? type.GetFields(bindingAttr.Value) : type.GetFields();
        return fields.Select(x => x.Name);
    }
    public static IDictionary<string, object> KeyValueList(this Type type, object obj,
        BindingFlags? propBindingAttr = null, BindingFlags? fieldBindingAttr = null)
    {
        Dictionary<string, object> result = new Dictionary<string, object>();
        PropertyInfo[] props = propBindingAttr.HasValue
            ? type.GetProperties(propBindingAttr.Value)
            : type.GetProperties();
        Array.ForEach(props, x => result.Add(x.Name, x.GetValue(obj)));
        FieldInfo[] fields = fieldBindingAttr.HasValue ? type.GetFields(fieldBindingAttr.Value) : type.GetFields();
        Array.ForEach(fields, x => result.Add(x.Name, x.GetValue(obj)));
        return result;
    }
    public static IDictionary<string, object> PropertyKeyValueList(this Type type, object obj,
        BindingFlags? bindingAttr = null)
    {
        Dictionary<string, object> result = new Dictionary<string, object>();
        PropertyInfo[] props = bindingAttr.HasValue ? type.GetProperties(bindingAttr.Value) : type.GetProperties();
        Array.ForEach(props, x => result.Add(x.Name, x.GetValue(obj)));
        return result;
    }
    public static IDictionary<string, object> FieldKeyValueList(this Type type, object obj,
        BindingFlags? bindingAttr = null)
    {
        Dictionary<string, object> result = new Dictionary<string, object>();
        FieldInfo[] fields = bindingAttr.HasValue ? type.GetFields(bindingAttr.Value) : type.GetFields();
        Array.ForEach(fields, x => result.Add(x.Name, x.GetValue(obj)));
        return result;
    }
    public static bool HasKey(this Type type, string key, BindingFlags? propBindingAttr = null,
        BindingFlags? fieldBindingAttr = null)
    {
        return type.Keys(propBindingAttr, fieldBindingAttr).Contains(key);
    }
    public static object GetValue(this Type type, string key, object obj, BindingFlags? propBindingAttr = null,
        BindingFlags? fieldBindingAttr = null)
    {
        IDictionary<string, object> propertyKeyValueList = PropertyKeyValueList(type, obj, propBindingAttr);
        if (propertyKeyValueList.ContainsKey(key))
        {
            return propertyKeyValueList[key];
        }
        IDictionary<string, object> fieldKeyValueList = FieldKeyValueList(type, obj, fieldBindingAttr);
        if (fieldKeyValueList.ContainsKey(key))
        {
            return fieldKeyValueList[key];
        }
        return null;
    }
}

调用示例:

dataTable.TableToClass<UserInfo>();
typeof(Object).GetAllConstructors();
typeof(Object).GetAllProperties();
typeof(Object).GetAllFields();
typeof(Object).GetAllMethods();
typeof(People).HasKey("cjavapy");
typeof(People).GetValue("Name", peopleObj);

推荐文档