Attribute (一)

本文导读

1、概念

2、自定义一个 Attribute


概念

      Attribute是一个特殊的类,我们知道 .NET 程序集 具有自描述的特性(由于元数据),Attribute和.NET的元数据一起,可用来向描述你的代码,或者在程序运行的时候影响应用程序的行为。

      和Attribute 密切相关的技术是反射

      在.NET 框架中有许多内置的 Attribute,如序列化、安全性、DllImport等

      看一个内置Attribute 的代码

using System;

static class App
{
    static void Main()
    {
        Lib l = new Lib();
        l.Fct();
    }
}

class Lib
{    
    [Obsolete]
    public void Fct(){}
}

结果

image

 

自定义一个 Attribute

     系统的Attribute我们不能修改,我们能做的是自定义Attribute。步骤如下:

1、写一个继承 System.Attribute 的类,类名是以 Attribute 结尾

2、用系统自带的AttributeUsage 设置 Attribute

AttributeUsage 中有三个成员我们需要关注 AttributeTargets、AllowMultiple 、Inherited  分别的表示 Attribute 的作用范围、是否允许多个 Attribute实例(Attribute是类,反射时创建实例)、是否允许继承

 

我们看例子

Inherited  的例子

目录结构

image

是否允许继承文件夹中有4个文件分别是 Attr.cs(自定义Attribute)、TestLib.cs(Attribute修饰的测试类)、App.cs(第三方验证程序,比如框架)、build.bat 编译命令

看代码

//Attr.cs 
using System;

namespace XXX.Common.Attr
{
    // 不允许属性继承
    [AttributeUsage(AttributeTargets.Class,Inherited = false)]
    public class AAttribute : Attribute {}

    // 允许属性继承
    [AttributeUsage(AttributeTargets.Class,Inherited = true)]
    public class BAttribute : Attribute {}
}


//---------------------------------------------------------
// TestLib.cs
using System;
using XXX.Common.Attr;

namespace XXX.Common.Lib
{
    [A]
    [B]
    public class BaseLib {}
    
    public class ExtendLib : BaseLib {}
}


//---------------------------------------------------------
// App.cs
using System;
using XXX.Common.Attr;
using XXX.Common.Lib;
using System.Reflection;

namespace XXX.Common.App
{
    static class App
    {
        static void Main()
        {
            ShowBase();
            Console.WriteLine("-----------------");
            ShowExtend();
        }
        
        static void ShowBase()
        {
            ShowHelper(typeof(BaseLib));
        }
        
        static void ShowExtend()
        {
            ShowHelper(typeof(ExtendLib));
        }
        
        static void ShowHelper(MemberInfo mi)
        {
            AAttribute a = Attribute.GetCustomAttribute(mi,typeof(AAttribute)) as AAttribute;
            BAttribute b = Attribute.GetCustomAttribute(mi,typeof(BAttribute)) as BAttribute;
            
            Console.WriteLine(a==null ? "没有AAttribute信息" : "有AAttribute信息");
            Console.WriteLine(b==null ? "没有BAttribute信息" : "有BAttribute信息");
        }
    }
}

build.bat 内容

csc /t:library Attr.cs
csc /t:library /r:Attr.dll TestLib.cs
csc /r:Attr.dll,TestLib.dll App.cs

运行结果:

image

 

AllowMultiple 允许重复 Attribute

看代码

// Attr.cs
using System;

namespace XXX.Common.Attr
{
    // 默认AllowMultiple 为false
    [AttributeUsage(AttributeTargets.Class)]
    public class AAttribute : Attribute {}

    [AttributeUsage(AttributeTargets.Class,AllowMultiple=true)]
    public class BAttribute : Attribute {}
}


//-----------------------------------
// TestLib.cs
using System;
using XXX.Common.Attr;

namespace XXX.Common.Lib
{
    [A]
    [A]
    public class Lib1{}

    [B]
    [B]
    public class Lib2{}
}

image 

 

综合例子

//Attr.cs
using System;

namespace XXX.Common.Attr
{
    [AttributeUsage(AttributeTargets.All)]
    public class HelperAttribute : Attribute
    {
        private string _url;
        private string _topic;
        
        public HelperAttribute(string url)
        {
            this._url = url;
        }
        
        public string Url
        {
            get {return this._url;}
        }
        public string Topic
        {
            get {return this._topic;}
            set {this._topic = value;}
        }
    }
}


//---------------------------------------
// TestLib.cs
using System;
using XXX.Common.Attr;

namespace XXX.Common.Lib
{
    [Helper("http://cnblogs.com/Aphasia")]
    public class TestLib
    {
        [Helper("http://cnblogs.com/Aphasia",Topic="阿飞的博客")]
        public void ShowBlog(){}
    }
}

//-----------------------------------------
// App.cs
using System;
using System.Reflection;
using XXX.Common.Lib;
using XXX.Common.Attr;

namespace XXX.Common.Application
{
    static class App
    {
        static void Main()
        {
            ShowHelp(typeof(TestLib));
            ShowHelp(typeof(TestLib).GetMethod("ShowBlog"));
        }
        
        static void ShowHelp(MemberInfo mi)
        {
            HelperAttribute attr = Attribute.GetCustomAttribute(mi,typeof(HelperAttribute)) as HelperAttribute;
            
            if(attr == null) {Console.WriteLine("No Help for {0}.",mi);}
            else 
            {
                Console.WriteLine("Help for {0}:",mi);
                Console.WriteLine(" Url={0},Topic={1}",attr.Url,attr.Topic);
            }        
        }            
    }
}

运行结果

image

 

 

第二篇预告

Attribute (二) 将谈Attribute在设计中的用途,拦截器、Builder 模式

本文完

原文地址:https://www.cnblogs.com/Aphasia/p/4336171.html