C#: Reflection

反射(Reflection): 就是能够在运行时刻查询到类型信息的进程。他有以下的各个部分,可以根据你应用的需要选择其中的一个或者某些来使用:
1.  Assembly:使用它来定义和加载一些Assembly, 加载存在于Assembly 中的modules,并且可以得到这个Assembly的类型,同时创建他的实例 MSN 原文: Use Assembly to define and load assemblies, load modules that are listed in the assembly manifest, and locate a type from this assembly and create an instance of it.
 
2.  Module : 可以使用它来查找到包含该 module Assembly 信息,并且可以得到该 module 中的各种类;同时你不单单可以得到所有的全局函数和其他变量,也可以得到定义在该 module 中的非全局方法 MSN 原文: Use Module to discover information such as the assembly that contains the module and the classes in the module. You can also get all global methods or other specific, nonglobal methods defined on the module.
 
3.  ConstructorInfo : 使用它你可以查找到一个构造函数的名字,参数,访问权限和实现的细节(比如说它是抽象的,还是虚拟的); 使用某个类型的 GetConstructors GetContructor 方法来运行他的构造函数 MSN 原文: Use ConstructorInfo to discover information such as the name, parameters, access modifiers (such as public or private), and implementation details (such as abstract or virtual) of a constructor. Use the GetConstructors or GetConstructor method of a Type to invoke a specific constructor.
 
4.  MethodInfo : 通过他您可以查找到某个方法的名字,返回类型,参数,访问权限和实现的细节(比如说它是抽象的,还是虚拟的?);它也提供两个方法来运行制定的方法,他们分别是: GetMethods GetMethod.Use MSN 原文: MethodInfo to discover information such as the name, return type, parameters, access modifiers (such as public or private), and implementation details (such as abstract or virtual) of a method. Use the GetMethods or GetMethod method of a Type to invoke a specific method.
 
5.  FieldInfo: 使用它你可以查找到 某个字段的名字,返回类型,参数,访问权限和实现的细节(比如说是否是静态的?);它提供了 get set 方法来访问字段。 MSN 原文: Use FieldInfo to discover information such as the name, access modifiers (such as public or private) and implementation details (such as static) of a field, and to get or set field values.
 
6. EventInfo:使用它你将可以查找到某一个事件的名字,事件句柄的数据类型,自定义的属性,声明的类型和相关的类型等等的信息,当然你可以增加或者去除一个事件。 MSN 原文: Use EventInfo to discover information such as the name, event-handler data type, custom attributes, declaring type, and reflected type of an event, and to add or remove event handlers.
 
7. PropertyInfo: 使用它你可以查找到某个属性的名字, 数据类型, 声明的类型,关联的类型 和只读或者可写状态等一些信息; 当然你可以得到和设置他的值。 MSN 原文: Use PropertyInfo to discover information such as the name, data type, declaring type, reflected type, and read-only or writable status of a property, and to get or set property values.
 
8.  MSN 原文: Use ParameterInfo to discover information such as a parameter's name, data type, whether a parameter is an input or output parameter, and the position of the parameter in a method signature.
 
9.  MSN 原文: Use CustomAttributeData to discover information about custom attributes when you are working in the reflection-only context of an application domain. CustomAttributeData allows you to examine attributes without creating instances of them.
看了上面的那么多字,你可以能还不知道怎么应用,不过没关系,下面将会提供一些例子,在看例子之前,我们先看看 Type 类。
 
System.Type
它是整个放射的中心,上面的各个部分都是围绕着他来进行的。他能够查询类型名字, 类型中包含的模块和名称空间,以及判断该类型是值类型还是引用类型。
1.  得到类型名字:
float f = 1.0f;
Type t = f.GetType();
Console.WriteLine(t.Name);// 这样就可以得到他的类型名字了。
2.  通过一个类型名字得到一个 Type:
Type t = Type.GetType(“System.Int32”);
Console.WriteLine(t.Name);
3.  下面把查询类型的一部分列出来:
Type t = Type.GetType(typeName);
t.IsAbstract;
t.IsAnsiClass;
t.IsArray;
t.IsEnum;
t.IsClass
……
Assembly的应用
在这里就介绍一个称为“插件”技术的例子作为对这部分的总结吧!
现在使用一个现实中的例子,我在上海的某某地段开了一个超级市场,里面有各种各种牌子的店铺,你可以在超级市场新开设店铺,当然有一些店铺因为生意不好,不得不退出超级市场。那么在程序里面应该怎么样来实现这个过程呢?因为店铺的开张或倒闭不是固定的,是动态的, 这样我们就不能够在主程序中固化这些店铺,这个时候就需要我们动态的加载这些店铺了,下面请看如下实现:
1.     开设超级市场:
首先我们需要一个商铺管理类,用它来管理开店和关闭店铺,代码如下:
    public class ShopManager
    {
        protected static ShopManager m_ShopManager;
        protected ShopManager()
        {
        }
        public static ShopManager GetShopManager()
        {
            if (m_ShopManager == null)
            {
                m_ShopManager = new ShopManager();
            }
            return m_ShopManager;
        }
        public List<string> GetShops()
        {
            List<string> shops = new List<string>();
            string pluginFolder = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "plugins");
            if (!System.IO.Directory.Exists(pluginFolder))
                return shops;
            foreach(string pluginFile in System.IO.Directory.GetFiles(pluginFolder, "*.dll"))
            {
                try
                {
                    Assembly assembly = Assembly.LoadFile(pluginFile);
                    foreach(Type type in assembly.GetTypes())
                    {
                        if(!type.IsClass || type.IsNotPublic) continue;
                        Type[] tempInterfaces = type.GetInterfaces();
                        if(((IList)tempInterfaces).Contains(typeof(IShop)))
                        {
                            IShop shop = (IShop)CreateInstance(type);
                            shops.Add(shop.GetShopName());
                        }
                    }
                }
                catch
                {
                }
            }
            return shops;
         }
 
        protected object CreateInstance(Type type, object[] args)
        {
            try
            {
                return Activator.CreateInstance(type, args);
            }
            catch (TargetInvocationException e)
            {
                throw e.InnerException;
            }
        }
        protected object CreateInstance(Type type)
        {
            return CreateInstance(type, null);
        }
    }
接着定义个抽象的商铺类,我们的管理类只知道这个类,代码如下:
    public interface IShop
    {
        string GetShopName();
}
最后定义我们的超级市场类,请看代码:
    public class Market
    {
        protected static Market m_Market;
        protected List<string> m_Shops = new List<string>();
        protected Market()
        {
            //get all shops
            m_Shops = ShopManager.GetShopManager().GetShops();
        }
        public void ShowShops()
        {
            foreach (string shop in m_Shops)
            {
                Console.WriteLine(shop);
            }
        }
        public static Market GetMarket()
        {
            if (m_Market == null)
            {
                m_Market = new Market();
            }
            return m_Market;
        }
    }
这样整个市场就建立起来了。接着看看我们怎么开设店铺。
2   开设店铺:
首先创建一个店铺的接口类,并提供一个函数叫着: string GetShopName();
接着你就可以创建属于你的店铺了,这些具体的店铺都必须继承制店铺的接口类,实现他的接口函数,至于你要自己要为你开设的店铺创建什么功能,是你自己的事情,超级市场是不会关心的。下面是两个店铺的例子:
新建一个Class Library工程,命名为NikeShop,接下来是具体的代码:
using System;
using System.Collections.Generic;
using System.Text;
 
using SuperMarket;
namespace Shop
{
    public class NikeShop : IShop
    {
        public string GetShopName()
        {
            return "Nike";
        }
    }
}
同样再创建一个工程,叫做AdidasShop,代码如下:
using System;
using System.Collections.Generic;
using System.Text;
 
using SuperMarket;
namespace Shop
{
    public class AdidasShop : IShop
    {
        public string GetShopName()
        {
            return "Adidas";
        }
    }
}
最后把你生成的店铺的 dll 拷贝到plugin的文件夹里面就可以了。当你从新进入超级市场(启动主程序)的时候就可以看到该店铺了
3   关闭倒闭的店铺:
怎么样来关闭店铺呢? 很简单,我们只需要把这个店铺对应的dll文件从plugin里面删除就行,等你下次运行的时候,你将看不到该店铺了。
基本上就这些了,有什么问题,请留言,谢谢!
 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值