欢迎莅临 SUN WU GANG 的园子!!!

世上无难事,只畏有心人。有心之人,即立志之坚午也,志坚则不畏事之不成。

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

注:以下代码仅供参考使用,实际使用过程,应根据实际场景--进行提取重构,提升复用效率......

简单理解,反射应用于加载动态库DLL,解析其内部实现.......

示例如下所示:注,该代码基于.NET 5 

  运行效果如下所示:

using System;
using System.Reflection;
using TestDLL;

namespace Reflection
{
    /// <summary>
    /// ---------------------C# 反射应用------------------
    /// 加载、调用(TestDLL.dll为例--应和启动程序同目录)、实例化...
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("-----------------加载 DLL------------");
            Assembly assembly = LoadDLL(@"TestDLL.dll"); //加载 DLL
            //Type type = assembly.GetType("TestDLL.ReflectionTest");
            Type type = GetTypeByNamespace(assembly, "TestDLL.ReflectionTest");

            Console.WriteLine("-----------------获取指定动态库的所有实例------------");
            GetTypes(assembly);

            Console.WriteLine("-----------------构造调用------------");
            object obj = GetStructMethod(type, "反射反射来一个");
            //GetStructAllMethod(type);//构造调用

            Console.WriteLine("-----------------普通方法调用------------");
            ReflectionTest show = obj as ReflectionTest;
            show.Show1();
            //temp.Show3<ReflectionTest>();
            //temp.Show4<ReflectionTest>("Show4入参测试");
            Console.WriteLine("-----------------私有方法调用------------");
            GetPrivateMethod(type, obj, "Show2");

            Console.WriteLine("-----------------泛型方法调用------------");
            //泛型方法调用
            GetMethodByName(type, obj, "Show3");
            GetMethodByNameAndParams(type, obj, "Show4", "有参泛型方法调用测试入参");

            Console.WriteLine("-----------------泛型类 + 泛型方法------------");
            //泛型类 + 泛型方法(一定要给定具体的类型参数) `1表示一个参数
            GetGenericMethod(assembly, "TestDLL.GenericClass`1", "GenericMethod");

            //设置属性和获取属性
            Console.WriteLine("-----------------设置属性和获取属性------------");
            GetProperty(assembly, "TestDLL.PropertyClass");

            Console.ReadLine();
        }

        private static void GetProperty(Assembly assembly, string propertyClass)
        {
            Type type = assembly.GetType(propertyClass);
            object obj = Activator.CreateInstance(type);
            int index = 0;
            foreach (var item in type.GetProperties())
            {
                Console.WriteLine("属性名称==" + item.Name);
                index++;
                //测试一把
                if (item.Name.Equals("Id")) item.SetValue(obj, index);
                if (item.Name.Equals("Name")) item.SetValue(obj, "Name" + index);
                if (item.Name.Equals("NickName")) item.SetValue(obj, "NickName" + index);
            }
        }

        private static void GetGenericMethod(Assembly assembly, string genericClass, string methodName)
        {
            Type type = assembly.GetType(genericClass).MakeGenericType(typeof(string));
            object obj = Activator.CreateInstance(type);
            var method = type.GetMethod(methodName).MakeGenericMethod(new Type[] { typeof(string) });
            method.Invoke(obj, new object[] { });
        }

        /// <summary>
        /// 泛型方法调用--无参
        /// </summary>
        /// <param name="type">Type type</param>
        /// <param name="obj">object obj</param>
        /// <param name="methodName">方法名称</param>
        private static void GetMethodByNameAndParams(Type type, object obj,
            string methodName, string paramStr)
        {
            //查找指定的方法
            var method = type.GetMethod(methodName);
            //指定泛型参数类型
            var temp = method.MakeGenericMethod(new Type[] { typeof(string) });
            temp.Invoke(obj, new object[] { paramStr });
        }

        /// <summary>
        /// 泛型方法调用--无参
        /// </summary>
        /// <param name="type">Type type</param>
        /// <param name="obj">object obj</param>
        /// <param name="methodName">方法名称</param>
        private static void GetMethodByName(Type type, object obj, string methodName)
        {
            //查找指定的方法
            var method = type.GetMethod(methodName);
            //指定泛型参数类型
            var temp = method.MakeGenericMethod(new Type[] { typeof(string) });
            temp.Invoke(obj, new object[] { });
        }

        /// <summary>
        /// 泛型方法调用
        /// </summary>
        /// <param name="type">Type type</param>
        /// <param name="obj">object obj</param>
        /// <param name="methodName">方法名称</param>
        private static void GetPrivateMethod(Type type, object obj, string methodName)
        {
            var method = type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.NonPublic);
            method.Invoke(obj, new object[] { });
        }

        /// <summary>
        /// 获取指定动态库的所有实例
        /// </summary>
        /// <param name="assembly">Assembly assembly</param>
        /// <returns></returns>
        private static Type[] GetTypes(Assembly assembly)
        {
            var temps = assembly.GetTypes();
            foreach (var item in temps)
            {
                Console.WriteLine("name==" + item.Name);
            }
            return temps;
        }

        /// <summary>
        /// 构造调--实例化
        /// </summary>
        /// <param name="type"></param>
        private static void GetStructAllMethod(Type type)
        {
            foreach (var ctor in type.GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic
                | BindingFlags.Public))
            {
                Console.WriteLine("构造方法如下:" + ctor.Name);
                foreach (var param in ctor.GetParameters())
                {
                    Console.WriteLine("构造方法的参数:" + param.ParameterType);
                }
            }
        }

        /// <summary>
        /// 构造调--实例化
        /// </summary>
        /// <param name="type"></param>
        private static object GetStructMethod(Type type, string paramStr)
        {
            //动态获取实例类型--var/object类型(无参构造调用)
            //var temp = Activator.CreateInstance(type);

            //动态获取实例类型--var/object类型(有参构造调用)
            var temp = Activator.CreateInstance(type, new object[] { paramStr });

            //私有构造方法调用() 
            var privateStruct = Activator.CreateInstance(type, true);

            return privateStruct;
        }

        /// <summary>
        /// 通过反射获取指定类型(TestDLL.dll为例)
        /// </summary>
        /// <param name="assembly">Assembly assembly</param>
        /// <param name="namespaceAll">Assembly assembly</param>
        /// <returns></returns>
        private static Type GetTypeByNamespace(Assembly assembly, string namespaceAll)
        {
            return assembly.GetType(namespaceAll);
        }

        /// <summary>
        /// 加载 DLL
        /// </summary>
        /// <returns></returns>
        private static Assembly LoadDLL(string dllName)
        {
            //建议使用方式
            Assembly assembly = Assembly.LoadFrom(dllName);//@"TestDLL.dll"

            //加载DLL文件  加载文件需在项目启动位置
            //Assembly assembly1 = Assembly.Load("TestDLL");

            //不建议使用方式
            //Assembly assembly3 = Assembly
            //    .LoadFrom(@"D:\常用dll整理包\C# 反射应用\Reflection\bin\Debug\net5.0\TestDLL.dll");
            //Assembly assembly4 = Assembly
            //    .LoadFile(@"D:\常用dll整理包\C# 反射应用\Reflection\bin\Debug\net5.0\TestDLL.dll");
            return assembly;
        }
    }
}

using System;

namespace TestDLL
{
    public class GenericClass<T>
    {
        public void GenericMethod<TType>()
        {
            Console.WriteLine("GenericMethod方法调用");
        }
    }
}

namespace TestDLL
{
    public class PropertyClass
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string NickName { get; set; }
    }
}

using System;

namespace TestDLL
{
    public class ReflectionTest
    {
        public ReflectionTest()
        {
            Console.WriteLine("私有调用无参构造方法成功");
        }

        //public ReflectionTest()
        //{
        //    Console.WriteLine("调用无参构造方法成功");
        //}

        public ReflectionTest(string paramValue)
        {
            Console.WriteLine("调用有参构造方法成功,参数=" + paramValue);
        }

        public void Show1()
        {
            Console.WriteLine("Show1普通方法调用", this.GetType());
        }

        private void Show2()
        {
            Console.WriteLine("Show2私有方法调用", this.GetType());
        }
        public void Show3<T>()
        {
            Console.WriteLine("Show3泛型方法调用", this.GetType());
        }

        public void Show4<T>(string name)
        {
            Console.WriteLine("Show4泛型方法调用,参数是==" + name, this.GetType());
        }
    }
}

using System;

namespace TestDLL
{
    public class ReflectionTest2
    {
        public ReflectionTest2()
        {
            Console.WriteLine("ReflectionTest2调用无参构造方法成功");
        }

        public ReflectionTest2(string paramValue)
        {
            Console.WriteLine("ReflectionTest2调用有参构造方法成功,参数=" + paramValue);
        }
    }
}

  

 

posted on 2023-01-03 16:27  sunwugang  阅读(149)  评论(0编辑  收藏  举报