NET之特性和性能,历史纠葛

1. 引言

本文将介绍以下内容:

attribute是.NET框架引入的有一技能亮点,由此大家有要求花点时间走进一个发觉attribute登堂入室的进口。因为.NET
Framework中选用了汪洋的定制特性来形成代码约定,[Serializable]、[Flags]、[DllImport]、[AttributeUsage]这个的结构,相信大家都见过呢,那么您是否了然其幕后的技巧。

• 定制
特性的基本概念和用法

提起特性,由于高级语言发展的历史原因,不免令人回看另一个耳熟能详的名字:属性。特性和总体性,往往给初学者或者从C++转移到C#的人歪曲的定义冲击。那么,什么是性质,什么是特色,二者的概念和不一致,用法与示范,将在本文做以概括性的下结论和比较,希望给你的驾驭带来收获。别的本文的主题以特色的介绍为主,属性的阐释重点杰出在二者的可比上,关于属性的越多论述将在另一篇焦点中详尽谈论,敬请关怀。

• 属性 与特征的不一致相比

2. 概念引入

• 反射 的简练介绍

2.1. 怎样是特色?

1. 引言

MADN的定义为:公共语言运行时允许添加类似重大字的讲述评释,叫做attributes,
它对先后中的元素进行标注,如类型、字段、方法和性质等。Attributes和Microsoft
.NET
Framework文件的元数据保存在一道,可以用来向运行时描述您的代码,或者在程序运行的时候影响应用程序的一举一动。

attribute是.NET框架引入的有一技巧亮点,因而我们有必不可少花点时间来精通本文的内容,走进一个
发现attribute登堂入室的进口。 因为.NET
Framework中应用了大气的定制特性来形成代码约定,
[Serializable]、[Flags]、[DllImport]、[AttributeUsage]那个的社团,相信大家都见过啊,那么您是否通晓其幕后的技术。

大家大致的下结论为:定制特性attribute,本质上是一个类,其为指标元素提供关乎附加音讯,并在运行期以反射的法门来博取附加音信。具体的性状达成格局,在接下去的议论中一连深刻。

提起特性,由于高级语言
发展的历史由来,不免令人回首另一个耳熟能详的名字:属性。特性和总体性,往往给初学者或者从C++转
移到C#的人歪曲的概念
冲击。那么,什么是性质,什么是特色,二者的定义和区分,用法与示范,将在本文做以概括性的计算和相比较,希望给你的知道带来收获。别的本文的主旨以特色的
介绍为主,属性的解说重点卓绝在双边的相比上,关于属性的更多论述将在另一篇大旨中详尽座谈,敬请关心。

2.2. 如何是性质?

2. 概念引入

特性是面向对象编程的基本概念,提供了对私家字段的走访封装,在C#中以get和set访问器方法已毕对可读可写属性的操作,提供了平凉和灵活的多寡访问封装。关于属性的定义,不是本文的要紧,而且相信半数以上的技术人员应该对性能有显然的定义。以下是概括的性质示例:

2.1. 哪些是特点?

ca88手机版登录网页 1

MADN的
定义为:公共语言运行时允许添加类似重大字的叙说表明,叫做attributes,
它对程序中的
元素举行标注,如类型、字段、方法和属性等。Attributes和Microsoft .NET
Framework文件的元数据保存在联名,可以用来向运行时描述您的代码,或
者在程序运行的时候影响应用程序的作为。

  ca88手机版登录网页 2

大家简要的下结论为:定制
特性attribute,本质上是一个类,其为对象元素提供关乎附加音讯,并在运转期以反射的格局来获取附加消息。具体的特征达成格局,在接下去的议论中一连深远。

2.3. 有别于与相比

2.2. 什么样是性质?

通过对定义的正本清源和野史的追思,大家知道特性和总体性只是在称呼上有过纠纷,在MSDN上有关attribute的粤语讲演照旧依旧属性,可是自己同意更常见的称呼:特性。在效劳上和利用上,二者其实远非太多模糊的定义交叉,由此也从没需求来比较其应用的异同点。本文则以特色的定义为主要,来啄磨其选取的场所和规则。

 属性是
面向对象编程的基本概念,提供了对个体字段的造访封装,在C#中以get和set访问器方法完毕对可读可写属性的操作,提
供了平安和灵活的多寡访问封装。关于属性的概念,不是本文的最首要,而且相信半数以上的技术人士应该对性能有明晰的概念。以下是简单的属性示例:

自己知道的定制特性,就是为对象元素,可以是数据集、模块、类、属性、方法、甚至函数参数等投入附加新闻,类似于注释,可是足以在运转期以反射的办法赢得。定制特性首要行使在体系化、编译器指令、设计格局等地点。

 

3. 通用规则

    public class MyProperty
    {
        //定义字段
        private string _name;
        private int _age;

定制特性可以应用的目的元素得以为:程序集(assembly)、模块(module)、类型(type)、属性(property)、事件(event)、字段(field)、方法(method)、参数(param)、重返值(return),应该全了。

        //定义属性,完结对_name字段的包裹
        public string Name
        {
            get { return (_name == null) ? string.Empty : _name; }
            set { _name = value; }
        }

定制特性以[,]花样表现,放在紧挨着的元素上,多少个特征可以选取于同一元素,特性间以逗号隔开,以下表达规则有效:[AttributeUsage][
Flags]、[AttributeUsage, Flags]、[Flags,
AttibuteUsageAttribute]、[AttributeUsage(), FlagesAttribute()]

        //定义属性,完毕对_age字段的卷入
        //参加对字段的范围控制
        public int Age
        {
            get { return _age; }
            set
            {
                if ((value > 0) && (value < 150))
                {
                    _age = value;
                }
                else
                {
                    throw new Exception(“Not a real age”);
                }
            }
        }
    }

attibute实例,是在编译期举办早先化,而不是运行期。

    public class MyTest
    {
        public static void Main(string[] args)
        {
            MyProperty myProperty = new MyProperty();
            //触发set访问器
            myProperty.Name = “Anytao”;
            //触发get访问器
            Console.WriteLine(myProperty.Name);
            myProperty.Age = 66;
            Console.WriteLine(myProperty.Age.ToString());
            Console.ReadLine();
        }
    }

C#允许以指定的前缀来表示特性所使用的靶子元素,提议如此来拍卖,因为显式处理可以清除可能带来的二义性。例如:
using System;

 

using System; 

2.3. 分化与比较

namespace Anytao.net 
{
    [assembly: MyAttribute(1)]          //应用于程序集
    [moduel: MyAttribute(2)]            //应用于模块
    pubic class Attribute_how2do
    {
        //
    } 
}

由此对定义的清淤和历史
的追忆,大家知晓特性和性质只是在称呼上有过纠纷,在MSDN上有关attribute的国语演说仍然仍然属性,可是我同意
更常见的称之为:特性。在效益上和使用上,二者其实并未太多模糊的概念交叉,因而也从未须求来比较其采取的异同点。本文则以特色的定义为关键,来研究其应用
的场面和规则。

定制特性类型,必须一向或者直接的继承自System.Attribute类,而且该项目必须有国有构造函数来创设其实例。

自己精晓的定制特性,就是
为目标元素,能够是数据集、模块、类、属性、方法、甚至函数参数等参与附加新闻,类似于注释,但是足以在运作期以反射的办法获取。定制特性首要运用在种类化、编译器指令、设计方式等方面。

具有自定义的特色名称都应有有个Attribute后缀,这是习惯性约定。

3. 通用规则

定制特性也足以使用在其他定制特性上,那一点也很好了然,因为定制特性本身也是一个类,坚守类的公有规则。例如很多时候我们的自定义定制特性会使用AttributeUsageAttribute特性,来支配什么利用新定义的特征。
[AttributeUsageAttribute(AttributeTarget.All),

  1. 定制特性能够利用的对象元素得以为:程序集(assembly)、模块(module)、类型(type)、属性(property)、事件(event)、字段(field)、方法(method)、参数(param)、重回值(return),应该全了。

  2. 定 制特性以[,]方式显示,放在紧挨着的要素上,多个特点可以行使于同一元素,特性间以逗号隔开,以下表明规则有效:[AttributeUsage][
    Flags]、[AttributeUsage, Flags]、[Flags,
    AttibuteUsageAttribute]、[AttributeUsage(), FlagesAttribute()]

  3. attibute实例,是在编译期进行早先化,而不是运行期。

  4. C#允许以指定的前缀来代表特性所使用的靶子元素,指出那样来拍卖,
    因为显式处理可以清除可能带来的二义性。例如:  

[AttributeUsageAttribute(AttributeTarget.All),
AllowMultiple = true, 
Inherited = true]
class MyNewAttribute: System.Attribute
{
//

using System; 

定制特性不会潜移默化使用元素的其余作用,只是约定了该因素具有的特质。

namespace Anytao.net 
{
    [assembly: MyAttribute(1)]          //应用于程序集
    [moduel: MyAttribute(2)]            //应用于模块
    pubic class Attribute_how2do
    {
        //
    } 
}

不无非抽象特性必须持有public访问限制。

 

特点常用来编译器指令,突破#define, #undefine, #if,
#endif的范围,而且进一步灵敏。

  1. 定制特性类型,必须平昔或者直接的持续自System.Attribute类,而且该品种必须有国有构造函数来成立其实例。

  2. 不无自定义的特点名称都应当有个Attribute后缀,那是习惯性约定。

  3. 定制特性也足以行使在其他定制特性上,这一点也很好驾驭,因为定
    制特性本身也是一个类,听从类的公有规则。例如很多时候我们的自定义定制特性会使用AttributeUsageAttribute特
    性,来决定什么利用新定义的表征。  

定制特性常用来在运行期得到代码注释新闻,以附加新闻来优化调试。

[AttributeUsageAttribute(AttributeTarget.All),
AllowMultiple = true, 
Inherited = true]
class MyNewAttribute: System.Attribute
{
//

定制特性可以应用在一些设计情势中,如工厂模式。

 

定制特性还常用于位标记,非托管函数标记、方法扬弃标记等任何方面。

  1. 定制特性不会潜移默化使用元素的任何意义,只是约定了该因素具有的
    特质。
  2. 享有非抽象特性必须持有public访
    问限制。
  3. 特色常用来编译器指令,突破#define,
    #undefine, #if, #endif的限量,而且越加灵活。
  4. 定制特性常用来在运行期获得代码注释新闻,以附加音信来优化调
    试。
  5. 定制特性可以使用在少数设计方式中,如工厂格局。

  6. 定制特性还常用于位标记,非托管函数标记、方法扬弃标记等其余方面。

4. 特色的选拔

4. 风味的应用

4.1. 常用特色

4.1. 常用特色

常用特色,也就是.NET已经提供的原有特性,事实上在.NET框架中已经提供了增进的原始特性由大家表明,以下精选出自我认为最常用、最特异的本来特性做以简练研究,当然那只是本人的一家之辞,亦不足道。我想询问特性,依旧从此处做为起源,从.NET提供的经文初步,或许是一种求知的走后门,希望能给大家以启示。

常用特色,也就是.NET已经提供的原始特性,事实上在.NET框架中
已经提供了增加的本来面目特性由咱们表明,以下精选出自我认为最常用、最登峰造极的原来特性做以简单研讨,当然这只是本人的一家之辞,亦不足道。我想询问特性,依旧从
那里做为起点,从.NET提供的经文起首,或许是一种求知的捷径,希望能给我们以启示。

AttributeUsage

  1. AttributeUsage

AttributeUsage特性用于控制什么选择自定义特性到目的元素。关于AttributeTargets、AllowMultiple、Inherited、ValidOn,请参阅示例表达和其他文档。大家曾经做了一定的介绍和示范表明,我们如故在实践中自己体会越来越多啊。

AttributeUsage特性用于控制什么运用自定义特性到目标元素。关于AttributeTargetsAllowMultipleInheritedValidOn,请参阅示例表明和其余文档。大家早就做了一定的介绍和示范表明,大家照旧在实践中自己体会更加多呢。

Flags

  1. Flags

以Flags特性来将枚举数值看作位标记,而非单独的数值,例如:

以Flags特性来将枚举数值看作位标记,而非单独的数值,例如: 

enum Animal
{
    Dog     = 0x0001,
    Cat     = 0x0002,
    Duck    = 0x0004,
  Chicken = 0x0008
}

enum Animal
{
    Dog     = 0x0001,
    Cat     = 0x0002,
    Duck    = 0x0004,
  Chicken = 0x0008
}

故而,以下达成就一定轻松,

据此,以下完毕就一定
轻松, 

Animal animals = Animal.Dog | Animal.Cat;
Console.WriteLine(animals.ToString());

Animal animals = Animal.Dog | Animal.Cat;
Console.WriteLine(animals.ToString());

请推测结果是怎么,答案是:”Dog,
Cat”。即使没有Flags特别,那里的结果将是”3″。关于位标记,也将在本种类的继承章回中有所交代,在此只做以研商止步。

请猜想结果是怎么,答
案是:”Dog, Cat”。假如没有Flags尤其,那里的结果将是”3″。关于位标记,也将在本体系的继承章回中有所交代,在此只做以探索止步。

DllImport

  1. DllImport

DllImport特性,可以让我们调用非托管代码,所以大家得以使用DllImport特性引入对Win32
API函数的调用,对于习惯了非托管代码的程序员来说,这一风味确实是救命的稻草。

DllImport特性,可以让大家调用非托管代码,所以大家得以选拔DllImport特性引入对Win32
API函数的调用,对于习惯了非托管代码的程序员来说,这一表征确实是救命的稻草。 

ca88手机版登录网页,using System;
using System.Runtime.InteropServices;

using System;
using System.Runtime.InteropServices;

namespace Anytao.net
{
    class MainClass 
    {
       [DllImport(“User32.dll”)]
       public static extern int MessageBox(int hParent, string msg, string caption, int type);

namespace Anytao.net
{
    class MainClass 
    {
       [DllImport(“User32.dll”)]
       public static extern int MessageBox(int hParent, string msg, string caption, int type);

       static int Main() 
       {
          return MessageBox(0, “How to use attribute in .NET”, “Anytao_net”, 0);
      }
    }
}

       static int Main() 
       {
          return MessageBox(0, “How to use attribute in .NET”, “Anytao_net”, 0);
      }
    }
}

Serializable

  1. Serializable

Serializable特性阐明了接纳的元素得以被序列化(serializated),体系化和反种类化是另一个可以深远座谈的话题,在此大家只是提出概念,长远的研讨有待以特其余宗旨来呈现,限于篇幅,此不赘述。

Serializable特性注明了利用的因素得以被连串化(serializated),
体系化和反序列化是另一个足以深远座谈的话题,在此我们只是提议概念,深入的商量有待以特其他主题来显现,限于篇幅,此不赘述。

Conditional

  1. Conditional

Conditional特性,用于规范编译,在调节时选取。注意:Conditional不可应用于数据成员和性能。

Conditional特性,用于规范编译,在调节时选拔。注意:Conditional不
可利用于数据成员和性能。

还有任何的重大特征,包涵:Description、DefaultValue、Category、ReadOnly、BrowerAble等,有时间足以深深切磋。

还有任何的最紧要特色,包涵:DescriptionDefaultValueCategoryReadOnlyBrowerAble等,
有时间可以深远钻研。

4.2. 自定义特性

4.2. 自定义特性

既然如此attribute,本质上就是一个类,那么大家就可以自定义更特定的attribute来满意个性化须要,只要坚守上述的12条规则,完毕一个自定义特性其实是很不难的,典型的兑现格局为:

既然如此attribute,本质上就是一个类,那么大家就足以自定义更特定的attribute来
知足个性化须要,只要遵守上述的12条规则,已毕一个自定义特性其实是很不难的,典型的贯彻格局为:

概念特性 

  1. 概念特性  

  [AttributeUsage(AttributeTargets.Class |
        AttributeTargets.Method,
        Inherited = true)]
    public class TestAttribute : System.Attribute
    {
        public TestAttribute(string message)
        {
            throw new Exception(“error:” + message);
        }
        public void RunTest()
        {
            Console.WriteLine(“TestAttribute here.”);
        }
    }

 

采纳目的元素 [Test(“Error Here.”)]

    [AttributeUsage(AttributeTargets.Class |
        AttributeTargets.Method,
        Inherited = true)]
    public class TestAttribute : System.Attribute
    {
        public TestAttribute(string message)
        {
            Console.WriteLine(message);
        }
        public void RunTest()
        {
            Console.WriteLine(“TestAttribute here.”);
        }
    }

[Test(“Error Here.”)]
        public void CannotRun()
        {
            //
        }

 

得到元素附加新闻

  1. 动用目的元素  

万一没有怎么机制来在运转期来获取Attribute的叠加信息,那么attribute就不曾什么样存在的含义。由此,.NET中以反射机制来落到实处在运行期获取attribute信息,完毕方式如下:

        [Test(“Error Here.”)]
        public void CannotRun()
        {
            //
        }

 public static void Main(string[] args)
        {
            Tester t = new Tester();
            t.CannotRun();

 

            Type tp = typeof(Tester);
            TestAttribute myAtt = (TestAttribute)Attribute.GetCustomAttribute((MemberInfo)tp, typeof(TestAttribute));
            myAtt.RunTest();
        }

  1. 取得元素附加音讯

5. 经文示例

假定没有啥样机制来在
运行期来获得Attribute的附加音讯,那么attribute就
没有啥存在的意思。因而,.NET中以反射机制来促成在运行期获取attribute音信,落成方式如下:  

using System;
using System.Reflection;                                 //应用反射技术取得特性音信

 

namespace Anytao.net
{
    //定制特性也得以应用在其余定制特性上,
    //应用AttributeUsage,来控制什么利用新定义的特性
    [AttributeUsageAttribute(AttributeTargets.All,       //可应用任何因素
        AllowMultiple = true,                            //允许拔取很多次
        Inherited = false)]                              //不继承到派生类
    //特性也是一个类,
    //必须连续自System.Attribute类,
    //命名规范为:”类名”+Attribute。        
    public class MyselfAttribute : System.Attribute
    {
        //定义字段
        private string _name;
        private int _age;
        private string _memo;

 

        //必须定义其构造函数,要是不定义有编译器提供无参默许构造函数
        public MyselfAttribute()
        {
        }
        public MyselfAttribute(string name, int age)
        {
            _name = name;
            _age = age;
        }

        public static void Main()
        {
            Tester t = new Tester();
            t.CannotRun();

        //定义属性
        //显著特性和特性不是四回事儿
        public string Name
        {
            get { return _name == null ? string.Empty : _name; }
        }

            Type tp = typeof(Tester);
            MethodInfo mInfo = tp.GetMethod(“CannotRun”);            
            TestAttribute myAtt = (TestAttribute)Attribute.GetCustomAttribute(mInfo, typeof(TestAttribute));
            myAtt.RunTest();
        }

        public int Age
        {
            get { return _age; }
        }

 

        public string Memo
        {
            get { return _memo; }
            set { _memo = value; }
        }

5. 经典示例

        //定义方法
        public void ShowName()
        {
            Console.WriteLine(“Hello, {0}”, _name == null ? “world.” : _name);
        }
    }

5.1 小菜一碟

    //应用自定义特性
    //可以以Myself或者MyselfAttribute作为特色名
    //可以给属性Memo赋值
    [Myself(“Emma”, 25, Memo = “Emma is my good girl.”)]
    public class Mytest
    {
        public void SayHello()
        {
            Console.WriteLine(“Hello, my.net world.”);
        }
    }

什么也不说了,看注释吧。

    public class Myrun
    {
        public static void Main(string[] args)
        {
            //怎么样以反射确定特性新闻
            Type tp = typeof(Mytest);
            MemberInfo info = tp;
            MyselfAttribute myAttribute =
                (MyselfAttribute)Attribute.GetCustomAttribute(info, typeof(MyselfAttribute));
            if (myAttribute != null)
            {
                //嘿嘿,在运行时翻看注释内容,是还是不是很爽
                Console.WriteLine(“Name: {0}”, myAttribute.Name);
                Console.WriteLine(“Age: {0}”, myAttribute.Age);
                Console.WriteLine(“Memo of {0} is {1}”, myAttribute.Name, myAttribute.Memo);
                myAttribute.ShowName();
            }

using System;
using System.Reflection;                                 //应用反射技术取得特性新闻

            //多点反射
            object obj = Activator.CreateInstance(typeof(Mytest));

namespace Anytao.net
{
    //定制特性也可以使用在任何定制特性上,
    //应用AttributeUsage,来决定什么运用新定义的特性
    [AttributeUsageAttribute(AttributeTargets.All,       //可应用任何因素
        AllowMultiple = true,                            //允许采用多次
        Inherited = false)]                              //不继承到派生类
    //特性也是一个类,
    //必须继承自System.Attribute类,
    //命名规范为:”类名”+Attribute。        
    public class MyselfAttribute : System.Attribute
    {
        //定义字段
        private string _name;
        private int _age;
        private string _memo;

            MethodInfo mi = tp.GetMethod(“SayHello”);
            mi.Invoke(obj, null);
            Console.ReadLine();
        }
    }
}

        //必须定义其构造函数,假诺不定义有编译器提供无参默许构造函数
        public MyselfAttribute()
        {
        }
        public MyselfAttribute(string name, int age)
        {
            _name = name;
            _age = age;
        }

啥也别想了,自己做一下试跳。

        //定义属性
        //明显特性和总体性不是四遍事儿
        public string Name
        {
            get { return _name == null ? string.Empty : _name; }
        }

总结:

        public int Age
        {
            get { return _age; }
        }

     特性 (Attribute)
描述怎么着将数据连串化,指定用于强制安全性的性状,并限定实时 (JIT)
编译器的优化,从而使代码易于调试。属性 (Attribute)
还是可以记录文件名或代码小编,或在窗体开发阶段控制控件和分子的可知性。

        public string Memo
        {
            get { return _memo; }
            set { _memo = value; }
        }

        //定义方法
        public void ShowName()
        {
            Console.WriteLine(“Hello, {0}”, _name == null ? “world.” : _name);
        }
    }

    //应用自定义特性
    //可以以Myself或者MyselfAttribute作 为特征名
    //可以给属性Memo赋值
    [Myself(“Emma”, 25, Memo = “Emma is my good girl.”)]
    public class Mytest
    {
        public void SayHello()
        {
            Console.WriteLine(“Hello, my.net world.”);
        }
    }

    public class Myrun
    {
        public static void Main(string[] args)
        {
            //怎么着以反射确定特性音信
            Type tp = typeof(Mytest);
            MemberInfo info = tp;
            MyselfAttribute myAttribute =
                (MyselfAttribute)Attribute.GetCustomAttribute(info, typeof(MyselfAttribute));
            if (myAttribute != null)
            {
                //嘿嘿,在运作时翻看注释内容,是或不是很爽
                Console.WriteLine(“Name: {0}”, myAttribute.Name);
                Console.WriteLine(“Age: {0}”, myAttribute.Age);
                Console.WriteLine(“Memo of {0} is {1}”, myAttribute.Name, myAttribute.Memo);
                myAttribute.ShowName();
            }

            //多点反射
            object obj = Activator.CreateInstance(typeof(Mytest));

            MethodInfo mi = tp.GetMethod(“SayHello”);
            mi.Invoke(obj, null);
            Console.ReadLine();
        }
    }
}

 啥也别
想了,自己做一下试行。

5.2 他山之石

  • MSDN认为,特性 (Attribute)
    描述怎么着将数据系列化,指定用于强制安全性的特性,并限定实时 (JIT)
    编译器的优化,从而使代码易于调试。属性 (Attribute) 还是可以够记录文件名或代码作者,或在窗体开发阶段控制控件和分子的可知性。

  • dudu
    Boss收藏的不胜枚举小说《Attribute在.net编程中的
    应用
    》,给您使用方面的诱导会众多,值得探究。

  • Alerander同志 的文山会海小说《手把手教 你写ORM(六)》中,也有很好的诠释。

  • idior的文章《Remoting基本原理及其扩大机制
    也有收获,因而补充。

6. 结论

 Attribute是.NET引入的一大特征技艺,但在和讯中商讨的不是广大,所以拿出自己的体会来分
享,希望就这一技巧主旨举行一番登堂入室的率领。更深层次的采纳,例如种类化、程序安全性、设计情势多地点都足以挖掘出闪耀的金子,那就是.NET在技术领域
带来的百变魅力吗。希望大家畅所欲言,来完善和增补作者在这方面的不周详和认知上的不长远,那将是小编最大的砥砺和引力。

You can leave a response, or trackback from your own site.

Leave a Reply

网站地图xml地图