文章出處

在通過Visual Studio創建的C#程序集中,都包含了一個AssemblyInfo.cs的文件,在這個文件中,我們常常會看到這樣的代碼

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

從這些代碼及他們的注釋中,我們大概知道他們是用來描述程序集的相關信息,那么是不是我們平常寫的代碼中的類、類成員是不是也有這樣的附加信息呢?答案是肯定的。比如最常見的位枚舉、調用另一種語言開發的dll...

    [Flags]
    enum Actions
    {
        None = 0,
        Read = 0x01,
        Write = 0x02,
        ReadWrite = Read | Write,
        Delete = 0x04
    }
  [DllImport("user32.dll")]
  public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

定制自己的Attribute

定制自己的Attribute類,首先要繼承System.Attribute,并用Attribute作為后綴。下面的例子中的DescriptionAttribute其實在System.ComponentModel下已近有實現,這里我們只是作為一個自己的簡單的例子

    //AttributeUsage的第一個參數,告訴編譯器這個特性應用的范圍,第二個參數指的是派生類及重寫成員是否也繼承該特性,第三個參數表示是否可以為類型或成員指定多個特性
    [System.AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
    sealed class DescriptionAttribute : Attribute
    {
        // See the attribute guidelines at 
        //  http://go.microsoft.com/fwlink/?LinkId=85236
        readonly string description;

        // This is a positional argument
        public DescriptionAttribute(string description)
        {
            this.description = description;

            // TODO: Implement code here
        }

        public string Description
        {
            get { return description; }
        }

        // This is a named argument
        public int NamedInt { get; set; }
    }

下面我們就用剛才自定義的特性,來簡單的完成一些事情,首先我們像下面那樣把剛才的枚舉類型加上我們定義的特性

    [Flags]
    [Description("文件的訪問")]
    enum Actions
    {
        None = 0,
        Read = 0x01,
        Write = 0x02,
        ReadWrite = Read | Write,
        Delete = 0x04
    }

那么加上這個特性有什么用呢?怎么體現他的作用呢?不要著急,我們這就來實現

    [Description("主程序")]
    class Program
    {
        static void Main(string[] args)
        {
            ClassDescriptionDisplay(typeof(Actions));
            ClassDescriptionDisplay(typeof(Program));
            Console.ReadKey();
        }

        static void ClassDescriptionDisplay(Type type)
        {
            if (type.IsDefined(typeof(DescriptionAttribute), false))//檢測類型是否包含此特性
            {
                DescriptionAttribute attrs = (DescriptionAttribute)type.GetCustomAttributes(typeof(DescriptionAttribute), false)[0];//獲取特性
                Console.WriteLine("{0}:{1}",type.Name,attrs.Description);
            }
            else
            {
                //另外的處理
            }
        }
    }

通過上面的代碼,現在我們知道,我們可以為類及他的成員添加好配置,然后在程序運行的過程中根據配置動態的去處理一些問題。其實這個也就是特性的最大功能。

應用

特性的應用范圍很廣,比如我們可以為實體類的各個屬性添加一個特性,這樣的話在保存數據的時候不用再一個個的去寫屬性的判斷,比如序列化的時候,只想序列化部分字段,但是要完成這些功能,還需要進一步學習反射的相關知識,這一篇我們的重點是在定制特性

    public class RegisterViewModel
    {
        [Required]
        [EmailAddress]
        [Display(Name = "電子郵件")]
        public string Email { get; set; }

        [Required]
        [StringLength(100, ErrorMessage = "{0} 必須至少包含 {2} 個字符。", MinimumLength = 6)]
        [DataType(DataType.Password)]
        [Display(Name = "密碼")]
        public string Password { get; set; }

        [DataType(DataType.Password)]
        [Display(Name = "確認密碼")]
        [Compare("Password", ErrorMessage = "密碼和確認密碼不匹配。")]
        public string ConfirmPassword { get; set; }
    }


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()