.NET之特性和性能。[你不能不掌握的.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函数的调用,对于习惯了非托管代码的程序员来说,这无异风味确实是救人之稻草。 

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编程中之
    应用》,给你下方面的启迪会众多,值得研究。

  • 亚历山大同志 的泛滥成灾文章《手把手教 你勾勒ORM(六)》中,也来很好之诠释。

  • idior的文章《Remoting基本原理及其扩展机制》
    也时有发生获取,因此补充。

6. 结论

 Attribute是.NET引入的同样深特色技艺,但当博客园中讨论的未是成百上千,所以将出团结之认知来划分
享,希望就顿时同一技术中心进行一番登堂入室的指引。更要命层次的用,例如序列化、程序安全性、设计模式多点都可挖掘有闪耀的金,这就算是.NET在技能世界
带来的百移魅力吧。希望大家畅所欲言,来宏观以及互补作者以即时面的不全面与认知及之非透,那以凡作者最要命的砥砺与动力。

相关文章

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

Leave a Reply

网站地图xml地图