程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 使用反射、特性簡化代碼,反射特性簡化代碼

使用反射、特性簡化代碼,反射特性簡化代碼

編輯:C#入門知識

使用反射、特性簡化代碼,反射特性簡化代碼


假設現在有一個學生類(Student)

    /// <summary>
    /// 學生類
    /// </summary>
    public class Student
    {   
        /// <summary>
        /// 名字
        /// </summary>
        private string name;
        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        /// <summary>
        /// 年齡
        /// </summary>
        public int Age { get; set; }

        /// <summary>
        /// 地址
        /// </summary>
        public string Address { get; set; }

        /// <summary>
        /// 性別
        /// </summary>
        public string Sex;
    }

如果需要判斷某些字段(屬性)是否為空,是否大於0,便有以下代碼:

        public static string ValidateStudent(Student student)
        {
            StringBuilder validateMessage = new StringBuilder();
            if (string.IsNullOrEmpty(student.Name))
            {
                validateMessage.Append("名字不能為空");
            }

            if (string.IsNullOrEmpty(student.Sex))
            {
                validateMessage.Append("性別不能為空");
            }

            if (student.Age <= 0)
            {
                validateMessage.Append("年齡必填大於0");
            }

            //...... 幾百行

            // 寫到這裡發現不對啊,如果必填項有20多個,難道我要一直這樣寫嗎!
            return validateMessage.ToString();
        }

這樣的代碼,重用性不高,而且效率低。

我們可以用特性,反射,然後遍歷屬性並檢查特性。

首先自定義一個【必填】特性類,繼承自Attribute

    /// <summary>
    /// 【必填】特性,繼承自Attribute
    /// </summary>
    public sealed class RequireAttribute : Attribute
    {
        private bool isRequire;
        public bool IsRequire
        {
            get { return isRequire; }
        }

        /// <summary>
        /// 構造函數
        /// </summary>
        /// <param name="isRequire"></param>
        public RequireAttribute(bool isRequire)
        {
            this.isRequire = isRequire;
        }
    }

然後用這個自定義的特性標記學生類的成員屬性:

    /// <summary>
    /// 學生類
    /// </summary>
    public class Student
    {   
        /// <summary>
        /// 名字
        /// </summary>
        private string name;
        [Require(true)]
        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        /// <summary>
        /// 年齡
        /// </summary>
        [Require(true)]
        public int Age { get; set; }

        /// <summary>
        /// 地址
        /// </summary>
        [Require(false)]
        public string Address { get; set; }

        /// <summary>
        /// 性別
        /// </summary>
        [Require(true)] 
        public string Sex;
    }

通過特性檢查類的屬性:

        /// <summary>
        /// 檢查方法,支持泛型
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="instance"></param>
        /// <returns></returns>
        public static string CheckRequire<T>(T instance)
        {
            var validateMsg = new StringBuilder();

            //獲取T類的屬性
            Type t = typeof (T);
            var propertyInfos = t.GetProperties();

            //遍歷屬性
            foreach (var propertyInfo in propertyInfos)
            {
                //檢查屬性是否標記了特性
                RequireAttribute attribute = (RequireAttribute) Attribute.GetCustomAttribute(propertyInfo, typeof (RequireAttribute));

                //沒標記,直接跳過
                if (attribute == null)
                {
                    continue;
                }

                //獲取屬性的數據類型
                var type = propertyInfo.PropertyType.ToString().ToLower();

                //獲取該屬性的值
                var value = propertyInfo.GetValue(instance);

                if (type.Contains("system.string"))
                {
                    if (string.IsNullOrEmpty((string) value) && attribute.IsRequire)
                        validateMsg.Append(propertyInfo.Name).Append("不能為空").Append(",");
                }
                else if (type.Contains("system.int"))
                {
                    if ((int) value == 0 && attribute.IsRequire)
                        validateMsg.Append(propertyInfo.Name).Append("必須大於0").Append(",");
                }
            }

            return validateMsg.ToString();
        }

執行驗證:

        static void Main(string[] args)
        {
            var obj = new Student()
            {
                Name = ""
            };
            Console.WriteLine(CheckRequire(obj));
            Console.Read();
        }

結果輸出:

有人會發現,Sex也標記了[Require(true)],為什麼沒有驗證信息,這是因為,Sex沒有實現屬性{ get; set; },GetProperties是獲取不到的。

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved