理解C#反射机制

反射是.NET中的重要机制,通过反射可以得到*.exe或*.dll等程序集内部的接口、类、方法、字段、属性、特性等信息,还可以动态创建出类型实例并执行其中的方法。
反射的功能很强大,任何复杂抽象的分层架构或者复杂的设计模式均是建立在这些基础之上的,比如我们要进行模块化、组件化开发,要严格的消除模块之间的耦合,要进行动态接口调用。开发这样强大而灵活的系统,必须要用反射才行,我们只要把它用在合适的位置,不仅能使代码变的清晰简洁,更能让它发挥出惊人的力量。

反射的用途

类型作用
Assembly定义和加载程序集,加载程序集清单中列出的模块,以及从此程序集中查找类型并创建该类型的实例。
Module了解包含模块的程序集以及模块中的类等,还可以获取在模块上定义的所有全局方法或其他特定的非全局方法。
ConstructorInfo了解构造器的名称、参数、访问修饰符(如public或private)和实现详细信息(如abstract或virtual)等。使用Type的GetConstructors或GetConstructor方法来调用特定的构造函数。
MethodInfo了解方法的名称、返回类型、参数、访问修饰符(如public或private)和实现详细信息(如abstract或virtual)等。使用Type的GetMethods或GetMethod方法来调用特定的方法。
FieldInfo了解字段的名称、访问修饰符(如public或private)和实现详细信息(如static)等,并获取或设置字段值。
EventInfo了解事件的名称、事件处理程序数据类型、自定义特性、声明类型和反射类型等,并添加或移除事件处理程序。
PropertyInfo了解属性的名称、数据类型、声明类型、反射类型和只读或可写状态等,并获取或设置属性值。
ParameterInfo了解参数的名称、数据类型、参数是输入参数还是输出参数等,以及参数在方法签名中的位置等。

System.Type类

System.Type类对于反射有很重要的作用。它是一个抽象的基类,Type有与每种数据类型对应的派生类,我们使用这个派生类的对象的方法、字段、属性来查找有关该类型的所有信息。
获取给定类型的Type值有三种常用方式:

  • 使用C# typeof运算符
    Type t=typeof(string);
  • 使用对象的GetType()方法
    string s=“guo”;Type t=s.GetType();
  • 调用Type类的静态方法GetType()
    Type t=Type.GetType(“System.String”);

获取程序集信息

namespace ReflectionTest
{
    class ReflectionHelper
    {
        public void GetAssemblyInfo()
        {
            Assembly assembly = Assembly.GetExecutingAssembly();
            Console.WriteLine("程序集全名:{0}", assembly.FullName);
            Console.WriteLine("程序集的版本:{0}", assembly.GetName().Version);
            Console.WriteLine("程序集初始位置:{0}", assembly.CodeBase);
            Console.WriteLine("程序集位置:{0}", assembly.Location);
            Console.WriteLine("程序集入口:{0}", assembly.EntryPoint);
            Type[] types = assembly.GetTypes();
            Console.WriteLine("程序集中包含的类型:");
            foreach (Type item in types)
            {
                Console.WriteLine("类:" + item.Name);
            }
        }
    }
}

这里写图片描述

获取类型信息

namespace ReflectionTest
{
    class ReflectionHelper
    {
        public void GetTypeInfo()
        {
            Type type = typeof(Person);
            Console.WriteLine("类型名:{0}", type.Name);
            Console.WriteLine("类全名:{0}", type.FullName);
            Console.WriteLine("命名空间:{0}", type.Namespace);
            Console.WriteLine("程序集名:{0}", type.Assembly);
            Console.WriteLine("模块名:{0}", type.Module);
            Console.WriteLine("基类名:{0}", type.BaseType);
            Console.WriteLine("是否类:{0}", type.IsClass);
            Console.WriteLine("类的公共成员:");
            MemberInfo[] members = type.GetMembers();
            foreach (MemberInfo memberInfo in members)
            {
                Console.WriteLine("{0}:{1}", memberInfo.MemberType, memberInfo);
            }
        }
    }
}

这里写图片描述

反射调用方法

namespace ReflectionTest
{
    class ReflectionHelper
    {
        public void InvokeMethod()
        {
            #region 方法一
            Assembly assembly1 = Assembly.Load("ReflectionTest");
            Type type1 = assembly1.GetType("ReflectionTest.Person");
            object obj1 = System.Activator.CreateInstance(type1);
            MethodInfo method1 = type1.GetMethod("Show");
            method1.Invoke(obj1, null);
            #endregion

            #region 方法二
            object obj2 = Assembly.Load("ReflectionTest").CreateInstance("ReflectionTest.Person");
            Type type2 = obj2.GetType();
            MethodInfo method = type2.GetMethod("Show");
            method.Invoke(obj2, null);
            #endregion
        }
    }
}

反射实现工厂模式

namespace ReflectionTest
{
    class Program
    {
        static void Main(string[] args)
        {
            //方法一
            AbsFruit absFruit = FruitFactory.CreateInstance<AbsFruit>("ReflectionTest", "Strawberry");
            absFruit.Show();
            //方法二
            //string fullTypeName = typeof (Strawberry).FullName;
            string fullTypeName = typeof (Strawberry).AssemblyQualifiedName;            
            AbsFruit absFruit2 = FruitFactory.CreateInstance<AbsFruit>(fullTypeName);
            absFruit2.Show();
        }
    }
}
namespace ReflectionTest
{
    public class FruitFactory
    {
        public static T CreateInstance<T>(string nameSpace,string className)
        {
            string fullClassName = nameSpace + "." + className;
            return (T)Assembly.Load(nameSpace).CreateInstance(fullClassName);
        }

        public static T CreateInstance<T>(string fullTypeName)
        {
            return (T)Activator.CreateInstance(Type.GetType(fullTypeName));
        }
    }
}
public abstract class AbsFruit
{
    protected string Name { get; set; }
    public abstract void Show();
}
class Strawberry:AbsFruit
{
    public Strawberry()
    {
        Name = "草莓";
    }
    public override void Show()
    {
        Console.WriteLine("水果类型:" + Name);
    }
}
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

changuncle

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值