说到模式,不得不说下c#里面的反射,正是利用了这种特性,很方便的实现了一些设计模式的想法。比如抽象工厂模式,不知道地球人看过微软4.0的Petshop没,里面的抽象工场模式就是利用反射实现的。
具体什么是反射呢?百度搜索的解释是这样地:
反射(fanshe)在中枢神经系统参与下,机体对内外环境刺激所作出的规律性反应。反射活动的结构基础是反射弧。高等动物和人的反射有两种:一种是在系统发育过程中形成并遗传下来,因而生来就有的先天性反射,称非条件反射。它是由于直接刺激感受器而引起的,通过大脑皮质下各中枢完成的反射。另一种是条件反射,是动物个体在生活过程中适应环境变化,在非条件反射基础上逐渐形成的后天性反射。它是由信号刺激引起,在大脑皮质的参与下形成的。根据结构基础的不同,又可把反射分为简单和复杂的两种。最简单的反射是单突触反射。复杂的反射,是神经中枢分布较广,靠联络神经元组成复杂的链锁。反射是实现机能调节的基本方式。反射弧中任何一部位被破坏,反射就不能实现。由于突触在结构与功能上的特性,决定了反射弧上冲动的传导只能由感受器传向效应器。
哈哈,为了不使地球人看这个文章无聊,所以添加介绍点生物知识。活跃下大脑细胞。
其实反射是这样描述的:程序集包含模块,而模块包含类型,类型又包含成员。反射则提供了封装程序集、模块和类型的对象。您可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从
现有对象中获取类型。然后,可以调用类型的方法或访问其字段和属性。
依据个人的肤浅了解,反射机制的采用在很大程度上依赖于.net 框架里面的metadata元数据,在受控代码编译以后生成的是metadata来描述元数据,所有的什么class,Delegate,Event ,interface,等这些东西都会加载相应的metadata到内存里面。当然,这些东西是存储在一个CLR-based编译器产生的module 里面的,这个东东加载就可以读到里面的东西,其优势是程序不加载也可以。可以把这些东西存到文件里面读出来(当让大多数时候还是程序编译的时候读的)。当我们读取metadata的过程,就是反射。
当然,这里又引出一个问题,就是广大公司面试的时候最喜欢考的一个题目,attributes(属性)和property(性质)的区别。从attribute和property的字义上理解,attribute应该是"特性",汉语上理解“特性“就是与生具来的属性,所以有人把它理解成“元属性“,”标签“的意思(以和property区别)也是合适的,property就可以理解为是“属性“–附加的性质;
attribute:修饰属性(定语)
property:是不同的属性(性质)
说白了,在.net里面
private string name; // C#中称为Field(字段),C++中称为Member Variable(成员变量),OOA/OOD中称为Attribute(属性)
public string Name { // C#中称为Property(属性)
get {
return name;
}
set {
name = value;
}
}
以上对那个私有字段的封装,添加了一个Name属性,通过对这个属性的访问,可以对私有字段name进行操作。这里就是所谓的propety。
而.net里面的attribute实际上是metadata描述的一类值,这种值是用来控制代码运行的方方面面,他可以被加入到class里面,也可以被加入到fields,methods里面,比如我们一般在类需要串行化的时候加入的[Serializable],还有在remoting时候创建的web service里面的方法前面的[WebMethod]描述。这些都是所谓的attribute。
下面给出一个网络上和书上很常见的运用反射的例子:
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
namespace ReflectionTest
{
[Serializable]
class Program
{
static void Main(string[] args)
{
Assembly assm = Assembly.LoadFrom(“ReflectionTest.exe”);
Type[] mytypes = assm.GetTypes();
foreach (Type t in mytypes)
{
Console.WriteLine(t.Name);
}
Type ht = typeof(HellowReflection);
MethodInfo[] mif = ht.GetMethods();
foreach (MethodInfo mi in mif)
{
Console.WriteLine(mi.Name);
}
Object obj=Activator.CreateInstance(ht);
string[] s={“MyFunTest”};
Object objname = Activator.CreateInstance(ht,s);
BindingFlags flags=BindingFlags.Public;
MethodInfo msayhi=ht.GetMethod(“MyFunTest”);
msayhi.Invoke(obj,null);
msayhi.Invoke(objname,null);
Console.ReadLine();
}
}
}
——————————————————————————
using System;
using System.Collections.Generic;
using System.Text;
namespace ReflectionTest
{
class HellowReflection
{
string myName = null;
public string MyName
{
get { return myName; }
set { myName = value; }
}
public HellowReflection(string name)
{
myName = name;
}
public HellowReflection()
: this(null)
{ }
public void niub()
{
if (myName == null)
{
Console.WriteLine(“hello !!!”);
}
else
{
Console.WriteLine(“hello “ + myName.ToString());
}
}
}
}