【FCL】何时使用反射?

本文详细介绍了反射技术的应用场景,包括在未编写完整代码时提前使用接口,通过反射调用动态加载的dll中的函数,以及运行时根据配置文件选择不同dll的情况。同时展示了如何在代码中使用反射技术获取程序集中的所有类型和方法,以及如何实例化这些类型并调用其方法。最后,通过一个具体示例说明了反射技术在设计灵活的软件架构中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

以下引用了:http://bbs.youkuaiyun.com/topics/350052774 该帖子里的回答。

using引入命名空间,并不等于编译器编译时加载该命名空间所在的程序集,程序集的加载决定于程序中对该程序集是否存在调用操作,如果代码中不存在任何调用操作则编译器将不会加载using引入命名空间所在程序集。因此,在源文件开头,引入多个命名空间,并非加载多个程序集,不会造成“过度引用”的弊端。

何时应用反射:1、假如你定义了接口MyInterface,然后让别人要写实现接口MyInterface的类A。但是在自己使用A的时候,其他人还没写A,可以使用反射技术。
       2、通过反射调用dll里的函数,后来这个dll改动了,或者换了一个新的dll,只要接口不变(如果变了,也可以通过配置文件获得),可以直接使用新的dll,而不需要修改你的程序。
              3、有些dll是在运行时才知道的。比如一个系统支持sql和access,而操作这两个不同数据库是用不同的dll的,可以通过配置来选择哪个数据库。

 

以下引用了:http://blog.youkuaiyun.com/tonglian/article/details/2271066中的内容

    有人也许疑问,既然在开发时就能够写好代码,干嘛还放到运行期去做,不光繁琐,而且效率也受影响。
这就是个见仁见智的问题了,就跟早绑定和晚绑定一样,应用到不同的场合。有的人反对晚绑定,理由是损耗效率,但是很多人在享受虚函数带来的好处的时侯还没有意识到他已经用上了晚绑定。这个问题说开去,不是三言两语能讲清楚的,所以就点到为止了。
    我的看法是,晚绑定能够带来很多设计上的便利,合适的使用能够大大提高程序的复用性和灵活性,但是任何东西都有两面性,使用的时侯,需要再三衡量。
接着说,运行期得到类型信息到底有什么用呢?
还是举个例子来说明,很多软件开发者喜欢在自己的软件中留下一些接口,其他人可以编写一些插件来扩充软件的功能,比如我有一个媒体播放器,我希望以后可以很方便的扩展识别的格式,那么我声明一个接口:
public   interface   IMediaFormat
{
    string   Extension   {get;}
    Decoder   GetDecoder();
}
这个接口中包含一个Extension属性,这个属性返回支持的扩展名,另一个方法返回一个解码器的对象(这里我假设了一个Decoder的类,这个类提供把文件流解码的功能,扩展插件可以派生之),通过解码器对象我就可以解释文件流。
那么我规定所有的解码插件都必须派生一个解码器,并且实现这个接口,在GetDecoder方法中返回解码器对象,并且将其类型的名称配置到我的配置文件里面。
这样的话,我就不需要在开发播放器的时侯知道将来扩展的格式的类型,只需要从配置文件中获取现在所有解码器的类型名称,而动态的创建媒体格式的对象,将其转换为IMediaFormat接口来使用。
这就是一个反射的典型应用。

 

以下代码非引用内容:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace Suggestion
{
    public class DynamicSample
    {
        public string Name { get; set; }

        public DynamicSample() { }

        public DynamicSample(string name)
        {
            this.Name = name;
        }

        public void SayHello()
        {
            Console.WriteLine("hello: " + Name);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            /*
             *  罗列程序集中所有类型
             */
            Console.WriteLine("获取程序集中的所有类型");
            Assembly a = Assembly.LoadFrom("Suggestion.exe");
            Type[] types = a.GetTypes();
            foreach (Type t in types)
            {
                Console.WriteLine(t.Name);
            }
            Console.ReadLine();

            /*
             * 罗列类型DynamicSample的所有方法
             */
            Console.WriteLine("获取所有方法");
            //如果DynamicSample已经定义了,可以用下面的语句
            //Type dt = typeof(DynamicSample);
            //如果还没定义DynamicSample的时候,只能用下面的语句
            Type dt = a.GetType("Suggestion.DynamicSample");
            MethodInfo[] mif = dt.GetMethods();
            foreach (MethodInfo mf in mif)
            {
                Console.WriteLine(mf.Name);
            }
            Console.ReadLine();
            
            /*
             * 实例化,并调用其函数
             */
            Console.WriteLine("实例化,并调用其中的某个方法"); 
            //调用无参构造函数
            Object obj = Activator.CreateInstance(dt);
            //调用一个参数的构造函数
            Object objName = Activator.CreateInstance(dt, new string[] { "glm" });
            MethodInfo sayhello = dt.GetMethod("SayHello");
            sayhello.Invoke(obj, null);
            sayhello.Invoke(objName, null);           
            Console.ReadLine();

            //下面使用dynamic简化映射
            dynamic dynamic1 = Activator.CreateInstance(dt);
            dynamic dynamic2 = Activator.CreateInstance(dt, new string[] { "glm" });
            dynamic1.SayHello();
            dynamic2.SayHello();

        }
    }    
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值