反射 type类 Assembly 本性分分快三计划

作者:编程技术

有关程序及其类型的多少被喻为元数据(matadata),他们保存在程序的次序聚焦(.dll卡塔 尔(英语:State of Qatar)。

  1. 程序是用来管理数据的,文本和特点都是数码,而大家先后自己(类的概念和BLC中的类卡塔尔那一个也是数额。
  2. 有关程序及其类型的数码被称为元数据(metadata),它们保存在程序的次序聚焦。
  3. 程序在运营时,可以查看别的程序集或其本人的元数据。一个运作的次序查看自个儿的元数据依旧此外程序集的元数据的行事称为反射。

反射的焦点类:System.Type类

  • 过多协理反射的类都投身System.Reflection命名空间中,他们是.net Reflection API的生龙活虎局地,所以在使用的反射的主次中日常都要采取System.Reflection的命名空间。
  • System. Type类包装了档期的顺序,由此是整整反射子系统的为主,那些类中包含了超多天性和办法,使用那一个属性和章程可以在运作时拿到类型的信息。
  • Type类派生于System.Reflection.MemberInfo抽象类

MemberInfo类中的只读属性

属性

描述

TypeDeclaringType

赢得注脚该成员的类或接口的种类

MemberTypesMemberType

得到成员的门类,这么些值用于提醒该成员是字段、方法、属性、事件、或构造函数

IntMetadataToken

收获与一定元数据有关的值

ModuleModule

获得一个表示反射类型所在模块的Module对象

StringName

成员的称呼

TypeReflectedType

反射的对象类型

请注意

  • MemberType属性的回来类型为MemberTypes,那是一个枚举,它定义了用来表示差别成员的类型值。那一个值包含:MemberTypes.Constructor, MemberTypes.Method, MemberTypes.Field, MemberTypes.Event, MemberTypes.Property。因而得以由此检查MemberType属性来规定成员的项目,举个例子,在MemberType属性的值为MemberTypes.Method时,该成员为格局
  • MemberInfo类还带有七个与特色相关的架空方法:
    1. GetCustomAttributes() :获得与主调对象关系的自定义个性列表。
    2. IsDefined(): 鲜明是否为主调对象定义了对应的特性。
    3. GetCustomAttributesData():再次回到有关自定义性情的新闻

当然除了MemberInfo类定义的艺术和总体性外,Type类自身也增添了大多天性和方法:如下表(只列出生机勃勃部分常用的,太多了,自身能够转定义Type类看下卡塔 尔(阿拉伯语:قطر‎

Type类定义的点子

方法

功能

ConstructorInfo[] GetConstructors()

拿到钦赐项目标构造函数列表

EventInfo[] GetEvents();

获得内定项目标大运列

FieldInfo[] GetFields();

获取钦命项指标字段列

Type[] GetGenericArguments();

拿到与已布局的泛型类型绑定的品种参数列表,纵然钦点项目标泛型类型定义,则赢得类型形参。对方岚早布局的花色,该列表就恐怕还要满含类型实参和种类形参

MemberInfo[] GetMembers();

拿到钦点项指标积极分子列表

MethodInfo[] GetMethods();

收获钦命项指标方法列表

PropertyInfo[] GetProperties();

得到钦赐项指向性质列表

下边列出Type类定义的常用的只读属性

Type类定义的性质

属性

功能

Assembly Assembly

获得钦命项目标程序集

TypeAttributes Attributes

获取拟定项指标特色

Type BaseType

拿到钦命项指标第一手基类型

String FullName

拿到钦赐项指标全名

bool IsAbstract

生机勃勃旦内定项目是用空想来欺骗别人类型,再次回到true

bool IsClass

只要内定项目是类,重返true

string Namespace

获取钦赐项目标命名空间

亟待领悟的Type首要事项:

1.对于程序中用到的每二个品类,CLCRUISER都会创制二个包涵那几个项目标Type类型的对象。

2.前后相继中用到的每叁个档次都会提到到独门的Type类的指标。

3.不管成立的类有多少个实例,独有叁个Type对象会涉及到具备的那个实例。

如图:三个运维的次序,他有五个MyClass对象和叁个OtherClass对象。注意:纵然有三个MyClass的实例,只会有一个Type对象来代表他。

分分快三计划 1

小编们能够从Type对象中得到须要精晓的有关项指标大约具有消息。

列一下常用的分子吧。

System.Type类部分的分子。

分分快三计划 2

 

 

is运算符:

  通过is运算符,可以判止呕标类型是或不是为一定项目,固然三种档期的顺序是同等连串,大概两个之间存在援用,装箱拆箱调换,则阐明三种等级次序是合营的。

class Program    {        static void Main(string[] args)        {            A a = new A();            B b = new B();            if (a is A)              {                Console.WriteLine("a is an A");   //这个打印,因为a 是 A 类型的对象            }            if (b is A)            {                //这个打印,因为b是B类型的对象,而B类型派生于A类型,由于b对象可以转换为A类型,因此b对象与A类型是兼容的,但是反过来就不成立,例如下面不打印                Console.WriteLine("b is an A because it is derived from");             }            if (a is B)            {                //这个不打印                Console.WriteLine("This won't display , because a not derived from B");            }            if (a is object)            {                //这个打印                Console.WriteLine("a is an object");            }            Console.ReadKey();        }    }    class A { }    class B : A { }
public static T TFactory<T>() where T : class
{
     Type ty = typeof(T);
     string spaceStr = ty.Namespace; 
     string fullStr = ty.FullName;
     Assembly ass = Assembly.Load(spaceStr); 
     object ob = ass.CreateInstance(fullStr, true);

     return (T)ob; 
}  

 

动用反射调用方法

地方大家经过反射获取到了类中的全部音信,上边咱们就再使用反射调用通过反射获取到的主意。

要调用反射获取到的不二法门,则需求在MethodInfo实例上调用Invoke() 方法。Invoke()的应用,在底下例子中示范,表达。

上面例子是:先通过反射获取到要调用的主意,然后使用Invoke()方法,调用获取到的钦定方法;

class MyClass    {        int x;        int y;        public MyClass(int i, int j)        {            x = i;            y = j;        }        private int sum()        {            return x   y;        }        public bool IsBetween(int i)        {            if (x < i && i < y) return true;            else return false;        }        public void Set(int a, int b)        {            Console.Write("Inside set.");            x = a;            y = b;            Show();        }        public void Set(double a, double b)        {            Console.Write("Inside set(double,double).");            x = (int)a;            y = (int)b;            Show();        }        public void Show()        {            Console.WriteLine("x:{0},y:{1}", x, y);        }    }    class InvokeMethDemo    {        static void Main()        {            Type t=typeof;           MyClass reflectOb = new MyClass(10, 20);           reflectOb.Show();  //输出为: x:10, y:20           MethodInfo[] mi = t.GetMethods();                      foreach (MethodInfo m in mi)           {               ParameterInfo[] pi = m.GetParameters();               if (m.Name.Equals("Set", StringComparison.Ordinal) && pi[0].ParameterType == typeof(int))               {                   object[] args = new object[2];                   args[0] = 9;                   args[1] = 10;                   //参数reflectOb,为一个对象引用,将调用他所指向的对象上的方法,如果为静态方法这个参数必须设置为null                   //参数args,为调用方法的参数数组,如果不需要参数为null                   m.Invoke(reflectOb, args);   //调用MyClass类中的参数类型为int的Set方法,输出为Inside set.x:9, y:10               }           }           Console.ReadKey();        }    }

前段时间心态放平,好好地去翻了翻书,看了看人家的博客。

如何加载程序集?
1,Assembly assembly1 = Assembly.Load("SomeAssembly");根据程序集的名字加载程序集,它会在本地目录和全局程序集缓存目录查找符合名字的程序集。
2,Assembly assembly2 = Assembly.LoadFrom(@"c:xxxxxxSomeAssembly.dll")//这里的参数是程序集的完整路径名,它不会在其他位置搜索。

GetMethods()方法的另后生可畏种方式

这种样式能够制定各样标志,已筛选想要获取的章程。他的通用方式为:MethodInfo[] GetMethods(BindingFlags bindingAttr)

BindingFlags是叁个枚举,枚举值有:

  1. DeclareOnly:仅获得钦点类定义的法子,而不获取所世襲的办法;
  2. Instance:获取实例方法
  3. NonPublic: 获取非公有方法
  4. Public: 获取共有方法
  5. Static:获取静态方法

GetMethods(BindingFlags bindingAttr)这一个艺术,参数能够选取or把五个或更多标识连接在一块,实际上起码要有Instance与Public(或NonPublic卡塔尔国标志。不然将不会获得别的措施。

class MyClass    {        int x;        int y;        public MyClass(int i, int j)        {            x = i;            y = j;        }        private int sum()        {            return x   y;        }        public bool IsBetween(int i)        {            if (x < i && i < y) return true;            else return false;                        }        public void Set(int a, int b)        {            x = a;            y = b;        }        public void Set(double a, double b)        {            x = (int)a;            y = (int)b;        }        public void Show()        {            Console.WriteLine("x:{0},y:{1}",x,y);        }    }    class ReflectDemo    {        static void Main(string[] args)        {            Type t=typeof;   //获取描述MyClass类型的Type对象            Console.WriteLine("Analyzing methods in " t.Name);  //t.Name="MyClass"            MethodInfo[] mi = t.GetMethods(BindingFlags.DeclaredOnly|BindingFlags.Instance|BindingFlags.Public);  //不获取继承方法,为实例方法,为公开的            foreach (MethodInfo m in mi) //遍历mi对象数组            {                Console.Write(m.ReturnType.Name); //返回方法的返回类型                Console.Write(" "   m.Name   "("); //返回方法的名称                ParameterInfo[] pi = m.GetParameters();  //获取方法参数列表并保存在ParameterInfo对象数组中                for (int i = 0; i < pi.Length; i  )                {                    Console.Write(pi[i].ParameterType.Name); //方法的参数类型名称                    Console.Write(" " pi[i].Name);  // 方法的参数名                    if (i   1 < pi.Length)                    {                        Console.Write(", ");                    }                }                Console.Write(")");                Console.WriteLine(); //换行            }            Console.ReadKey();        }    }

地点例子,可以看到只展现了Myclass类突显定义的公用方法。private int sum()也不显得。

一时候自身在想这是个怎样事物,能干啥。

特点目的:

typeof运算符:

  as ,is 能够测量检验两体系型的包容性。但大多数场合下,还须求得到有个别项目标现实性消息。那就用到了typeof,它能够回去与具象品种相关的System.Type对象,通过System.Type对象能够去顶此类型的表征。后生可畏旦获得给定类型的Type对象,就足以经过应用该目的定义的各类质量,字段,方法来得到项指标求实音信。Type类包罗了重重分子,在接下去的反射中再详尽座谈。上面轻巧的事必躬亲Type对象,调用它的多个个性。

static void Main(string[] args)        {            Type t=typeof(StringBuilder);            Console.WriteLine(t.FullName);  //FullName属性返回类型的全称            if (t.IsClass)            {                Console.WriteLine("is a class"); //打印            }            if (t.IsSealed)  //是否为密封类            {                Console.WriteLine("is Sealed");  //打印            }            Console.ReadKey();        }

获取Type对象

object类包涵了一个称为GetType的措施,他回到对实例的Type对象的引用。

是因为每二个体系最后都是从object世襲的,所以作者么能够在任何项目对象上应用GetType方法来得到她的Type对象。

Student stu = new Student();
Type type = stu.GetType();//stu可以时任何一个对象实例化后

上边演示一下二个基类跟派生子类。在foreach循环中输出类的名字以至公用字段的名字。

基类与派生类:

class BaseClass //基类
{
    public int BaseField = 0;
}

class DerivedClass : BaseClass //派生类
{
    public int DerivedField = 0;
}

因此反射输出类音信:

BaseClass bc = new BaseClass();    //基类
DerivedClass dc = new DerivedClass();//派生类

BaseClass[] bca = new BaseClass[] { bc, dc };

foreach (var v in bca)
{
    Type type = v.GetType();
    Console.WriteLine("Type:{0}",type.Name);//输出类名称

    FieldInfo[] fields = type.GetFields();//获取所有公用字段
    foreach (var f in fields)
         Console.WriteLine("Field:{0}",f.Name);//输出公用字段名称
}

出口结果为:

分分快三计划 3

类名与公用属性全体被输出了。

我们仍然为能够透过typeof运算符来获取Type对象。

只需提供项目名作为操作数,他就能够回去Type对象的援引(平时都会用在泛型方法中),如代码所示。

Type type = typeof(BaseClass);

怎么样是特点?

获得Type对象的构造函数

在这里以前的阐明中,由于MyClass类型的对象是都以显式创设的,由此利用反射技艺调用MyClass类中的方法是尚未其余优势的,还不如以普通格局调用方便轻便吗。不过,假诺指标是在运营时动态创设的,反射作用的优势就能够呈现出来。在这里种景况下,要先得到几个构造函数列表,然后调用列表中的有个别构造函数,创造一个该项指标实例。通过这种体制,能够在运作时实例化大肆等级次序的靶子,而不用在宣称语句中钦点项目。

class MyClass    {        int x;        int y;        public MyClass(int i)        {                    x = y   i;        }        public MyClass(int i, int j)        {                        x = i;            y = j;        }        public int sum()        {            return x   y;        }    }    class InvokeConsDemo    {        static void Main()        {            Type t = typeof;            int val;            ConstructorInfo[] ci = t.GetConstructors();  //使用这个方法获取构造函数列表            int x;            for (x = 0; x < ci.Length; x  )            {                ParameterInfo[] pi = ci[x].GetParameters(); //获取当前构造函数的参数列表                if (pi.Length == 2) break;    //如果当前构造函数有2个参数,则跳出循环            }            if (x == ci.Length)            {                return;            }            object[] consargs = new object[2];            consargs[0] = 10;            consargs[1] = 20;            object reflectOb = ci[x].Invoke;  //实例化一个这个构造函数有两个参数的类型对象,如果参数为空,则为null            //实例化后,调用MyClass中的方法            MethodInfo[] mi = t.GetMethods(BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance);            foreach (MethodInfo m in mi)            {                if (m.Name.Equals("sum", StringComparison.Ordinal))                {                    val = (int)m.Invoke(reflectOb, null);  //由于实例化类型对象的时候是用的两个参数的构造函数,所以这里返回的结构为30                    Console.WriteLine(" sum is "   val);  //输出 sum is 30                }            }            Console.ReadKey();        }    }

认真风姿浪漫看是或不是有一些哇塞~,十分酷的感觉。

Conditional性情(指标是背后的方法卡塔尔:

概述反射

  • 由此反射可以提供类型音信,从而使得大家开荒职员在运营时能够使用那几个新闻构造和行使对象。
  • 反射机制允许程序在实践进度中动态地充足各个功效。

总结

反射作者只是初窥门径,如若有错误的地点请各位大佬指正。

反射确定不会只输出这一个名字。

反射还足以设置类型里公用的值。仍然为能够调用类型中公用的方法。

等到下风流倜傥篇讲啊。

我们可以为单个结构应用多个特性。有下面两种添加方式
    独立的特性片段相互叠在一起
        [Serializable]
        [MyAttribute("Simple class","Version 3.57")]
    单个特性片段,特性之间使用逗号间隔
        [Serializable,MyAttribute("Simple class","Version 3.57")]

运转时类型标志

  • 运营时类型标记,能够在程序实行时期剖断对象类型。举个例子利用它亦可方便地领悟基类援用指向了何等类型对象。
  • 运转时类型标识,能事先测验有些强制类型转变操作,能还是不可能得逞,进而防止无效的强制类型调换非常。
  • 在c#中有多个援救RTTI的机要字:is 、 as 、typeof。 上面依次介绍他们

那是由此反射工厂来创设实例:

预订义类型(int long 和string等),BCL中的类型(Console,IEnumerable等)和技士自定义类型(MyClass,MyDel等卡塔尔国。 种种档期的顺序皆有友好的积极分子和天性。

as运算符:

  在运维时期施行类型调换,并且能够使得类型转变失败不抛非凡,而回到一个null值,其实as也足以充作叁个is运算符的简化备选格局。

class Program    {        static void Main(string[] args)        {            A a = new A();            B b = new B();            if (a is B)            {                b = a;   //由于a变量不是B类型,因此这里将a变量转换为B类型是无效的。            }            else            {                b = null;            }            if (b ==null)            {                //这个打印                Console.WriteLine("The cast in b=a is not allowed");             }            //上面使用as运算符,能够把两部合二为一。            b = a as B;   //as类型先检查强制类型转换的有效性,如果有效,则执行强类型转换过程。这些都在这一句完成。            if (b == null)            {                //这个打印                Console.WriteLine("The cast in b=a is not allowed");            }            Console.ReadKey();        }    }    class A { }    class B : A { }

反射

比非常多顺序都要管理多少,富含读,写,操作和显式数据。

不过,对于某个程序来讲,他们操作的不是数字,文本或图表,而是程序和程序类型笔者的音讯。

将利用了特征的程序结构叫做目标设计用来赢得和应用元数据的次第(对象浏览器卡塔 尔(阿拉伯语:قطر‎叫做特性的买主 .NET预约了重重特色,大家也能够申明自定义特性

获得情势的有关新闻

只要有了Type对象就足以选择GetMethodInfo()方法赢得此类型帮助的不二诀要列表。该方法再次回到几个MethodInfo 对象数组,MethodInfo对象描述了主调类型所帮衬的方法,他放在System.Reflection命名空间中

MethodInfo类派生于MethodBase抽象类,而MethodBase类世袭了MemberInfo类。因而我们能够利用这两个类定义的脾气和艺术。比如,使用Name属性获得方法名称。这里有三个基本点的积极分子:

    1. ReturnType属性 :为Type类型的对象,能够提供方式的归来类型音信
    2. GetParameters()方法 :重返参数列表,参数音信以数组格局保留在PatameterInfo对象中。PatameterInfo类定义了多量陈说参数音信的性质和艺术。这里也列出五个常用的属性 :Name(包涵参数名称音讯的字符串卡塔 尔(阿拉伯语:قطر‎,ParameterType。

下边代码,小编将使用反射获得类中所帮忙的秘诀,还会有方法的音信。

class MyClass    {        int x;        int y;        public MyClass(int i, int j)        {            x = i;            y = j;        }        public int sum()        {            return x   y;        }        public bool IsBetween(int i)        {            if (x < i && i < y) return true;            else return false;                        }        public void Set(int a, int b)        {            x = a;            y = b;        }        public void Set(double a, double b)        {            x = (int)a;            y = (int)b;        }        public void Show()        {            Console.WriteLine("x:{0},y:{1}",x,y);        }    }    class ReflectDemo    {        static void Main(string[] args)        {            Type t=typeof;   //获取描述MyClass类型的Type对象            Console.WriteLine("Analyzing methods in " t.Name);  //t.Name="MyClass"            MethodInfo[] mi = t.GetMethods();  //MethodInfo对象在System.Reflection命名空间下。            foreach (MethodInfo m in mi) //遍历mi对象数组            {                Console.Write(m.ReturnType.Name); //返回方法的返回类型                Console.Write(" "   m.Name   "("); //返回方法的名称                ParameterInfo[] pi = m.GetParameters();  //获取方法参数列表并保存在ParameterInfo对象数组中                for (int i = 0; i < pi.Length; i  )                {                    Console.Write(pi[i].ParameterType.Name); //方法的参数类型名称                    Console.Write(" " pi[i].Name);  // 方法的参数名                    if (i   1 < pi.Length)                    {                        Console.Write(", ");                    }                }                Console.Write(")");                Console.WriteLine(); //换行            }            Console.ReadKey();        }    }

出口结果为:Analyzing methods inMyClass MyClass(int i, int j) int sum()bool IsBetween void Set(int a, int b) void Set(double a, double b) void Show()

bool Equals(object obj) int GetHashCode() Type GetType() string ToString()

小心:这里出口的除却MyClass类定义的享有办法外,也会彰显object类定义的共有非静态方法。那是因为c#中的全部项目都世襲于object类。其余,这个消息实际程序运营时动态拿到的,并没有需求预先领会MyClass类的概念

来探视那一个反光是个什么样东西啊,遵照笔者的明白 书上的指引来大致粗略的写一下反光

 

接收反射

地点的列术都感到了,这里的行使。

透过利用Type类定义的法门和性格,我们能够在运营时收获类型的种种现实音讯。那是一个百般有力的意义。大家只要得到类型消息,就可以调用其构造函数,方法,和总体性。可知,反射是同意采纳编写翻译时不可用的代码的。

由于Reflection API超多,这里不容许全体的介绍他们(这里要是完全的牵线,据书上说要一本书,厚书卡塔 尔(阿拉伯语:قطر‎。然则,Reflection API是遵守一定逻辑设计的。由此,只要通晓有些接口的应用方法,就能够推而广之的利用剩余的接口。

这里本身列出各样首要的反光技巧:

  1. 得到方式的音信
  2. 调用方法
  3. 协会对象
  4. 从程序聚焦加载类型

在比相当多类别的浩大地方都发掘了三个一齐的术语---反射

 

从程序集获得类型

在在此以前边的演讲中得以看来二个类别的全体音讯都能够通过反射得到,可是MyClass类型本人,大家却未有做出获取。固然前段时间的论述实例,能够动态分明MyClass类的音讯,可是他们都是依照以下事实:预先明白类型名,况兼在typeof语句中接纳它拿走Type对象。就算这种模式或然在很三种状态下都很管用,可是要抒发反射的成套效果,大家还索要解析程序集的开始和结果来动态鲜明程序的可用类型。

依附Reflection API,能够加载程序集,获取它的相关新闻并创设其公共可用类型的实例。通过这种体制,程序可以搜索其条件,利用地下效果,而无需在编写翻译时期显式的定义他们。那是一个可怜有效,且令人喜悦的概念。

为了表达什么收获程序聚集的项目,作者创立三个文件。第贰个文件定义后生可畏组类,第一个文本则反射各类类的信息。 代码效果如下。

1.那上边代码是要编写翻译生成MyClass.exe文件的

class MyClass    {        int x;        int y;        public MyClass(int i)        {            x = y   i;        }        public MyClass(int i, int j)        {            x = i;            y = j;        }        public int sum()        {            return x   y;        }    }    class Demo    {        static void Main()        {            Console.WriteLine("hello word !");            Console.ReadKey();        }    }

2.这下边包车型大巴代码是获得下面生成程序集的

class Class3    {        static void Main() {            Assembly asm = Assembly.LoadFrom(@"C:UserslenovoDocumentsvisual studio 2010ProjectsReflection_testConsoleApplication1binDebugMyClass.exe");  //加载指定的程序集            Type[] alltype = asm.GetTypes();  //获取程序集中的所有类型列表            foreach (Type temp in alltype)            {                Console.WriteLine(temp.Name);  //打印出MyClass程序集中的所有类型名称 MyClass , Demo            }            Console.ReadKey();               }    }

下边获得到了,程序聚集的连串,如若想操作程序聚焦类型中的方法,则面前面我们累述的措施是二个标准的。

  原来的书文地址

也自身比着写了五个泛型反射方法。还算精晓了一小部分,写个记录。

 

public static List<T> ToList<T>(this DataTable dt)
{
    if (dt == null || dt.Rows.Count == 0)
    {
        return default(List<T>);
    }

    List<T> list = new List<T>();
    Type type = typeof(T);   
    PropertyInfo[] per = type.GetProperties(); 

    foreach (DataRow row in dt.Rows) 
    {
        T entity = Activator.CreateInstance<T>();
        foreach (PropertyInfo p in per)
        {
           object obj = Convert.ChangeType(row[p.Name], p.PropertyType); 
           p.SetValue(entity, obj);
        }
        list.Add(entity);
    }

    return list;
}

别的预订义天性:

次第在运行时,能够查阅其余程序集或其本身的元数据。三个周转的主次查看自身的元数据或别的程序的元数据的行为称为"反射"。

反射命名空间:System.Reflection

 

那是将Datatable里的数据反射到LIst集结中:

分分快三计划 4

Type类

BCL(基类库)申明了三个叫作Type的抽象类,他被设计用来含有类型的风味。使用那一个类能让我们拿到程序选用的门类的音信。

鉴于Type是抽象类,因而他不可能有实例。而是在运维时,CLRubicon(公共语言运行库)从Type(RunTimeType)派生的类的实例,Type富含了项目标音讯。

当我们要访谈这么些实例时,CLRAV4不会重回派生类的引用而是Type基类的援引,

自定义天性:应用天性的语法和事先见过的别的语法非常不生机勃勃致。你只怕会感觉天性跟结构是一丝一毫不相同的项目,其实不是,天性只是某些特殊结构的类。全体的性状类都派生自System.Attribute。

上例子代码:

我们可以将特性应用到字段和属性等程序结构上。我们还可以显示的标注特性,从而将它应用到特殊的目标结构。要使用显示目标,在特性片段的开始处放置目标类型,后面跟冒号。例如,如下的代码用特性装饰方法,并且还把特性应用到返回值上。
[return:MyAttribute("This value ...","Version2.3")]
[method:MyAttribute("Print....","Version 3.6")]
public long ReturnSettings(){
...
c#定义了10个标准的特性目标。
event    field    method    param    property    return    type    typevar    assembly    module
其中type覆盖了类,结构,委托,枚举和接口。
typevar指定使用泛型结构的类型参数。
我们在源代码中将特性应用于程序结构;
编译器获取源代码并且从特性产生元数据,然后把元数据放到程序集中;
消费者程序可以获取特性的元数据以及程序中其他组件的元数据。注意,编译器同时生产和消费特性。

关于特性的命名规范,特性名使用Pascal命名法(首字母大写),并且以Attribute后缀结尾,当为目标应用特性时,我们可以不使用后缀。例如对于SerializableAttribute和MyAttributeAttribute这两个特性,我们把他们应用到结构是可以使用Serializable和MyAttribute。
Conditional特性允许我们包括或取消特定方法的所有调用。为方法声明应用Conditional特性并把编译符作为参数来使用。
定义方法的CIL代码本身总是会包含在程序集中(没有定义对应的宏,那么加上特性的方法不会被调用,但是依然会被编译成数据在程序集当中),只是调用代码会被插入或忽略。 

#define DoTrace //注释掉就不会调用加上这个Conditional特性的方法,反之不注释就会调用

class Program{
    [Conditional("DoTrace")] 
    static void TraceMessage(string str){
        Console.WriteLine(str);
    }
    static void Main(){
        TraceMessage("Start of Main");
        Console.WriteLine("Doing work in Main.")
        TraceMessage("End of Main");
    }
}

声称自定义性格:

 

先看看如何使用特性。特性的目的是告诉编译器把程序结构的某组元数据嵌入程序集。我们可以通过把特性应用到结构来实现。
在结构前放置特性片段来应用特性;
特性片段被方括号包围,特性片段包括特性名和特性的参数列表;
应用了特性的结构成为特性装饰。

案例1
[Serializable]                //特性
public class MyClass{
    // ...
}
案例2
[MyAttribute("Simple class","Version 3.57")]    //带有参数的特性
public class MyClass{
    //...
}

 

至于Type的机要事项如下:

七个特征:

System.Type类部分成员:

运用性情:

Obsolete天性->.NET预订义性格(目的是后边的艺术卡塔 尔(阿拉伯语:قطر‎:

[AttributeUsage(AttributeTarget.Class)]
public sealed class ReviewCommentAttribute:System.Attribute{
    public string Description{get;set;}
    public string VersionNumber{get;set;}
    public string ReviewerID{get;set;}
    public ReviewerCommentAttribute(string desc,string ver){
        Description = desc;
        VersionNumber = ver;
    }
}

 

 

程序中用到的每一个类型都会涉及到独门的Type类的靶子。 不管成立的类型有稍微个示范,独有一个Type对象会涉嫌到持有这几个实例。

 

 

Assembly类在System.Reflection命名空间中定义,它允许访问给定程序集的元数据,它也包含了可以加载和执行程序集。

 

一个程序可能在其生命周期中经历多次发布,而且很可能延续多年。在程序生命周期的后半部分,程序员经常需要编写类似功能的新方法替换老方法。处于多种原因,你可能不再使用哪些调用过时的旧方法的老代码。而只想用新编写的代码调用新方法。旧的方法不能删除,因为有些旧代码也使用的旧方法,那么如何提示程序员使用新代码呢?可以使用Obsolete特性将程序结构标注为过期的,并且在代码编译时,显示有用的警告信息。
class Program{
    [Obsolete("Use method SuperPrintOut")]    //将特性应用到方法并给予提示USe method SuperPrintOut
    static void PrintOut(string str){
        Console.WriteLine(str);
    }
    [Obsolete("Use method SuperPrintOut",true)]//这个特性的第二个参数表示是是否应该标记为错误(不能编译,运行不了),而不仅仅是警告。
    static void PrintOut(string str){
        Console.WriteLine(str);
    }
    static void Main(string[] args){
        PrintOut("Start of Main");
    }
}

 

 

Assembly对象的应用:

什么是元数据,什么是反射:

出于 Type是抽象类,由此不能够运用它去实例化对象。

特色(attribute)是生机勃勃种允许大家向程序的次序集增韩元数据的语言结构。它是用来保存程序结构音讯的某种特殊类型的类。

节制天性的使用:

 

BCL表明了三个名字为Type的抽象类,它被规划用来含有类型的风味。使用这些类的对象能让我们获取程序行使的类别的消息。

 

 

分分快三计划 5

特性        意义
CLSCompliant    声明可公开的成员应该被编译器检查是否符合CLS。兼容的程序集可以被任何.NET兼容的语言使用
Serializable    声明结构可以被序列化
NonSerialized    声明结构不可以被序列化
DLLImport    声明是非托管代码实现的
WebMethod    声明方法应该被作为XML Web服务的一部分暴露
AttributeUsage    声明特性能应用到什么类型的程序结构。将这个特性应用到特性声明上

 

 

1,获取程序集的全名 string name = assembly1.FullName;
2,遍历程序集中定义的类型     Type[] types = theAssembly.GetTypes();
            foreach(Type definedType in types){
                //
            }
3,遍历程序集中定义的所有特性(稍后介绍)
    Attribute[] definedAttributes = Attribute.GetCustomAttributes(someAssembly);

DebuggerStepThrough个性(调节和测量试验对比平价卡塔尔:

对于程序中用到的每三个项目,CLMurano都会创建二个蕴含那个类型音讯的Type类型的对象。

 

AttributeTarget枚举的积极分子:

 

可以由此右键属性查看项方今后相继集的门路: 

上边大家大家来学习怎么着利用Type类来反光数据,以至哪些运用本性来给品种添日币数据。 Type位于System.Reflection命名空间下

有一个很重要的预定义特性可以用来应用到自定义特性上,那就是AttributeUsage特性,我们可以使用它来限制特性使用在某个目标类型上。
例如,如果我们希望自定义特性MyAttribute只能应用到方法上,那么可以用如下形式使用AttributeUsate:
    [AttributeUsage(AttributeTarget.Method)]
    public sealed class MyAttributeAttribute : System.Attribute{
    ...
    AttributeUsage有是三个重要的公共属性如下:
    ValidOn    保存特性能应用到的目标类型的列表,构造函数的第一个参数就是AttributeTarget            类型的枚举值
    Inherited    一个布尔值,它指示特性是否会被特性类所继承    默认为true
    AllowMutiple    是否可以多个特性的实例应用到一个目标上 默认为false

MyClass my = new MyClass();
Assembly assem = my.GetType().Assembly;//通过类的type对象得到它所在的前后相继集 Assembly
Console.WriteLine(assem.FullName);

访谈特性(花费特点):

All        Assembly Class    Constructor    Delegate    Enum    Event    Field
GenericParameter    Interface    Method        Module    Parameter Property    ReturnValue Struct


多个参数之间使用按位或|运算符来组合
AttributeTarget.Method|AttributeTarget.Constructor

Type类

声明一个特性类和声明其他类一样。有下面的注意事项
    声明一个派生自System.Attribute的类
    给它起一个以后缀Attribute结尾的名字
(安全起见,一般我们声明一个sealed的特性类)
特性类声明如下:
    public sealed class MyAttributeAttribute : System.Attribute{
...
特性类的公共成员可以是
    字段
    属性 
    构造函数
}

 

始建和采纳个性:

自定义本性常常坚决守护的规范:

品质中有个出口路径(生成在这里个目录下会有三个exe文件卡塔 尔(阿拉伯语:قطر‎:

构造函数(使用天性就能够调用卡塔 尔(阿拉伯语:قطر‎:

特性类的构造函数的声明跟普通类一样,如果不写系统会提供一个默认的,可以进行重载

构造函数的调用
[MyAttribute("a value")]    调用特性类的带有一个字符串的构造函数

[MyAttribute("Version 2.3","Mackel")]    //调用特性类带有两个字符串的构造函数


构造函数的实参,必须是在编译期间能确定值的常量表达式
如果调用的是无参的构造函数,那么后面的()可以不写

 

特性类应该表示目标结构的一些状态
如果特性需要某些字段,可以通过包含具有位置参数的构造函数来收集数据,可选字段可以采用命名参数按需初始化
除了属性之外,不要实现公共方法和其他函数成员
为了更安全,把特性类声明为sealed
在特性声明中使用AttributeUsage来指定特性目标组

调用者音信本性CallerFilePath(放在参数前面,参数正是指标卡塔尔:

 

构造函数中的地点参数和命名参数:

调用者信息特性可以访问文件路径,代码行数,调用成员的名称等源代码信息。
这个三个特性名称为CallerFilePath,CallerLineNumber和CallerMemberName
这些特性只能用于方法中的可选参数
public static void PrintOut(string message,[CallerFilePath] string filename="",[CallerLineNumber]int lineNumber = 0,[CallerMemberName]string callingMember=""){
    Console.WriteLine("Message:" message);
    Console.WriteLine("Line :" lineNumber);
    Console.WriteLine("Called from:" callingMember);
    Console.WriteLine("Message :" message);
}
1,我们可以使用IsDefined方法来,通过Type对象可以调用这个方法,来判断这个类上是否应用了某个特性
    bool isDefined = t.IsDefined( typeof(AttributeClass),false )
    第一个参数是传递的需要检查的特性的Type对象
    第二个参数是一个bool类型的,表示是否搜索AttributeClass的继承树
2,object[] attArray = t.GetCustomAttributes(false);
    它返回的是一个object的数组,我们必须将它强制转换成相应类型的特性类型
    bool的参数指定了它是否搜索继承树来查找特性
    调用这个方法后,每一个与目标相关联的特性的实例就会被创建

 

我们在单步调试代码的时候,常常希望调试器不要进入某些方法。我们只想执行该方法,然后继续调试下一行。DebuggerStepThrough特性告诉调试器在执行目标代码时不要进入该方法调试。有些方法小并且毫无疑问是正确的,在调试时对其反复单步调试只能徒增烦恼。要小心使用该特性,不要排除了可能出现bug的代码。
    该特性位于System.Diagnostics命名空间下
    该特性可用于类,结构,构造方法,方法或访问器
class Program{
    int _x=1;
    int X{
        get{return _x;};
        [DebuggerStepThrough]
        set{
            _x=_x*2;
            _x =value;
        }
    }
    public int Y{get;set;}
    [DebuggerStepThrough]
    void IncrementFields(){
        X  ;
        Y  ;
    }
    static void Main(){
        Program p = new Program();
        p.IncrementFields();
        p.X = 5;
        Console.WriteLine("P.X:" p.X " p.Y:" p.Y);
        Console.ReadKey();
    }
}

1, 天性类的后缀以Attribute结尾
2, 需求后续自System.Attribute
3, 日常意况下表明为 sealed
4, 日常景观下 性子类用来代表指标结构的后生可畏对状态(定义一些字段可能性质, 日常不定义方法)

成员        成员类型        描述
Name        属性        返回类型的名字
Namespace    属性        返回包含类型声明的命名空间
Assembly        属性        返回声明类型的程序集。
GetFields        方法        返回类型的字段列表
GetProperties    方法        返回类型的属性列表
GetMethods    方法        返回类型的方法列表

获取Type对象有两种方式
    1,Type t = myInstance.GetType();//通过类的实例来获取Type对象,每一个类对应一个type对象,这个type对象存储了这个类 有哪些方法跟哪些数据 哪些成员
        在object类有一个GetType的方法,返回Type对象,因为所有类都是从object继承的,所以我们可以在任何类型上使用GetType()来获取它的Type对象,一个类中的数据 是存储在对象中的, 但是type对象(与类的对象是没关系的,累的对象存的是值)只存储类的成员(只存类定义的成员/属性/方法不存成员的值)
    2,Type t = typeof(ClassName);//直接通过typeof运算符和类名获取Type对象

获取里面的属性
FieldInfo[] fi = t.GetFields();
foreach(FieldInfo f in fi){
    Console.WriteLine(f.Name " ");//只能得到public的字段
}

 

我们可以通过使用assembly和module目标名称来使用显式目标说明符把特性设置在程序集或模块级别。
    程序集级别的特性必须放置在任何命名空间之外,并且通常放置在AssemblyInfo.cs文件中
    AssemblyInfo.cs文件通常包含有关公司,产品以及版权信息的元数据。

[assembly: AssemblyTitle("ClassLibrary1")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ClassLibrary1")]
[assembly: AssemblyCopyright("Copyright ©  2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")] 

案例:

Assembly类(程序和类的集合卡塔 尔(阿拉伯语:قطر‎:

全局天性:

public sealed class MyAttributeAttribute:System.Attribute{
    public string Description;
    public string Ver;
    public string Reviewer;
    public MyAttributeAttribute(string desc){
        Description = desc;
    }
}
    //位置参数(按照构造函数中参数的位置) 
            //命名参数,按照属性的名字进行赋值
[MyAttribute("An excellent class",Reviewer = "Amy McArthur",Ver="3.12.3")]

分分快三计划 6

[AttributeUsage(AttributeTargets.Class)]//表示该特性类还行到的程序结构有哪些(类/属性/方法卡塔 尔(阿拉伯语:قطر‎

本文由分分快三计划发布,转载请注明来源

关键词: 分分快三计划 详解 C# NET 反射