亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C#特性怎么定義

發布時間:2022-03-09 13:41:34 來源:億速云 閱讀:162 作者:iii 欄目:開發技術

本篇內容主要講解“C#特性怎么定義”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“C#特性怎么定義”吧!

一、什么是特性

特性(Attribute)是用于在運行時傳遞程序中各種元素(比如類、方法、結構、枚舉、組件等)的行為信息的聲明性標簽。您可以通過使用特性向程序添加聲明性信息。一個聲明性標簽是通過放置在它所應用的元素前面的方括號([ ])來描述的。

特性(Attribute)用于添加元數據,如編譯器指令和注釋、描述、方法、類等其他信息。.Net 框架提供了兩種類型的特性:預定義特性和自定義特性。

特性的語法如下:

[attribute(positional_parameters, name_parameter = value, ...)]
element

特性(Attribute)的名稱和值是在方括號內規定的,放置在它所應用的元素之前。positional_parameters 規定必需的信息,name_parameter 規定可選的信息。

二、預定義特性

Obsolete特性

這個預定義特性標記了不應被使用的程序實體。它可以讓您通知編譯器丟棄某個特定的目標元素。例如,當一個新方法被用在一個類中,但是您仍然想要保持類中的舊方法,您可以通過顯示一個應該使用新方法,而不是舊方法的消息,來把它標記為 obsolete(過時的)。

語法如下:

[Obsolete(
   message
)]
[Obsolete(
   message,
   iserror
)]

 其中:

  • 參數 message,是一個字符串,描述項目為什么過時的原因以及該替代使用什么。

  • 參數 iserror,是一個布爾值。如果該值為 true,編譯器應把該項目的使用當作一個錯誤。默認值是 false(編譯器生成一個警告)。

請看下面的一個小例子:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyAttribute
{
    [Obsolete("請不要使用該類了,該類已經過時了,請使用什么代替")]
    public class Student
    {
        public int Id { get; set; }
        public string Name { get; set; }

        public string Accont { get; set; }

        public long QQ { get; set; }

        public string Answer([Custom]string name)
        {
            return $"This is {name}";
        }
    }
}

上面的例子中,在Student類上面使用了Obsolete特性來標注該類已經過時了。編譯代碼結果:

C#特性怎么定義

三、自定義特性

.Net 框架允許創建自定義特性,用于存儲聲明性的信息,且可在運行時被檢索。該信息根據設計標準和應用程序需要,可與任何目標元素相關。

創建并使用自定義特性包含四個步驟:

  • 聲明自定義特性

  • 構建自定義特性

  • 在目標程序元素上應用自定義特性

  • 通過反射訪問特性

1、聲明自定義特性

在上面的例子中,使用F12查看Obsolete的定義:

C#特性怎么定義

從上面的截圖中可以看出,.NET框架中的預定義特性是繼承自Attribute類,所以要自定義一個特性,只需要該類繼承自Attribute即可,下面定義一個Custom自定義特性:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyAttribute
{
    /// <summary>
    /// 自定義Custom特性
    /// </summary>
    public class CustomAttribute :Attribute
    {

    }
}

注意:所有的特性默認以Attribute結尾,但聲明的時候可以不以Attribute結尾。

2、構建自定義特性

每個特性必須至少有一個構造函數。必需的定位( positional)參數應通過構造函數傳遞。下面的代碼演示了CustomAttribute類:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyAttribute
{
    /// <summary>
    /// 自定義Custom特性
    /// </summary>
    public class CustomAttribute :Attribute
    {
        /// <summary>
        /// 無參構造函數
        /// </summary>
         public CustomAttribute()
        {

        }

        /// <summary>
        /// 有參構造函數
        /// </summary>
        /// <param name="id"></param>
        public CustomAttribute(string description)
        {
            this.Description = description;
        }

        /// <summary>
        /// 屬性
        /// </summary>
        public string Description { get; set; }

        /// <summary>
        /// 字段
        /// </summary>
        public string Remark = null;

        public void Show()
        {
            Console.WriteLine("This Is CustomAttribute");
        }
    }
}

3、在目標程序元素上應用自定義特性

通過把特性放置在緊接著它的目標(類、方法、屬性、字段等)上面,來應用該特性:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyAttribute
{
    [Obsolete("請不要使用該類了,該類已經過時了")]
    [Custom("這是Custom自定義特性")]
    public class Student
    {
        public int Id { get; set; }
        public string Name { get; set; }

        public string Accont { get; set; }

        public long QQ { get; set; }

        public string Answer([Custom]string name)
        {
            return $"This is {name}";
        }
    }
}

注意:

1、如果在聲明自定義特性的時候使用了Attribute結尾,那么應用自定義特性的時候可以把Attribute省略掉;如果聲明的時候沒有以Attribute結尾,那么應用自定義特性的時候就不能把Attribute省略掉。

2、默認情況下相同的特性只能應用一次,如果想應用多次特性,那么需要給特性添加AttributeUsage特性,CustomAttribute特性修改如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyAttribute
{
    /// <summary>
    /// 自定義Custom特性
    /// </summary>
    [AttributeUsage(AttributeTargets.All,AllowMultiple =true,Inherited =true)]
    public class CustomAttribute :Attribute
    {
        /// <summary>
        /// 無參構造函數
        /// </summary>
         public CustomAttribute()
        {

        }

        /// <summary>
        /// 有參構造函數
        /// </summary>
        /// <param name="id"></param>
        public CustomAttribute(string description)
        {
            this.Description = description;
        }

        /// <summary>
        /// 屬性
        /// </summary>
        public string Description { get; set; }

        /// <summary>
        /// 字段
        /// </summary>
        public string Remark = null;

        public void Show()
        {
            Console.WriteLine("This Is CustomAttribute");
        }
    }
}

其中,AttributeTargets是枚舉值,F12轉到定義可以查看AttributeTargets的所有枚舉值:

C#特性怎么定義

AttributeTargets的枚舉值表示Custom特性可以應用在哪些目標上面。例如:AttributeTargets的枚舉值是Class,則表示CustomAttribute只能應用在類上面。這里枚舉值是All,表示可以在任何類型上面使用該特性。默認情況下枚舉值是All。

AllowMultiple表示該特性是否可以在類型上面多次使用:

C#特性怎么定義

這里AllowMultiple的值為true,表示可以在類型上面多次使用該特性。如果為false,則表示只能使用一次。默認情況下是false。

Inherited表示該特性是否可以由子類繼承:

C#特性怎么定義

默認情況下Inherited為true。

這是在看Student類:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyAttribute
{
    [Obsolete("請不要使用該類了,該類已經過時了")]
    [Custom("這是Custom自定義特性")]//使用有參構造
    [Custom()]//使用無參構造
    public class Student
    {
        public int Id { get; set; }

        /// <summary>
        /// 在屬性上面使用Custom特性
        /// </summary>
        [Custom("這是Name屬性")]
        public string Name { get; set; }

        public string Accont { get; set; }

        public long QQ { get; set; }

        /// <summary>
        /// 在方法和參數上面使用Custom特性
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        [Custom("這是Answer方法")]
        public string Answer([Custom("這是方法參數")]string name)
        {
            return $"This is {name}";
        }
    }
}

注意:如果一個類型上面多次使用了同一種特性,那么特性可以寫在一起,中間用逗號隔開,例如上面的定義和下面的是同樣的效果:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyAttribute
{
    [Obsolete("請不要使用該類了,該類已經過時了")]
    [Custom("這是Custom自定義特性"),Custom,Custom(),Custom(Remark ="備注")]

    public class Student
    {
        public int Id { get; set; }

        /// <summary>
        /// 在屬性上面使用Custom特性
        /// </summary>
        [Custom("這是Name屬性")]
        public string Name { get; set; }

        public string Accont { get; set; }

        public long QQ { get; set; }

        /// <summary>
        /// 在方法、方法參數、方法的返回值上面使用Custom特性
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        [Custom("這是Answer方法")]//方法上面應用特性
        [return:Custom()] //方法的返回值應用特性
        public string Answer([Custom("這是方法參數")]string name)
        {
            return $"This is {name}";
        }
    }
}

注意:在Web API中FromBaby和FromUri就是給方法的參數應用特性。

4、通過反射訪問特性

定義一個Manager類來管理特性:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace MyAttribute
{
    /// <summary>
    /// 管理特性
    /// </summary>
    public class Manager
    {
        public static void Show(Student student)
        {
            // 獲取類型
            Type type = typeof(Student); //或者使用student.GetType();
            // 找到類型上面的特性    type.IsDefined表示找類型上面的特性
            if (type.IsDefined(typeof(CustomAttribute), true))//檢查有沒有  性能高
            {
                //GetCustomAttribute 獲取特性 type.GetCustomAttribute表示找到類型上面定義的特性,表示調用構造函數創建一個CustomAttribute類型的對象
                CustomAttribute attribute = (CustomAttribute)type.GetCustomAttribute(typeof(CustomAttribute), true);
                // attribute.Description表示特性類里面的屬性  attribute.Remark表示特性類里面的字段
                Console.WriteLine($"{attribute.Description}_{attribute.Remark}");
                attribute.Show();
            }


            #region 獲取ID屬性上面定義的特性
            // 獲取Id屬性
            PropertyInfo property = type.GetProperty("Id");
            //檢查Id屬性上面是否定義了CustomAttribute特性
            if (property.IsDefined(typeof(CustomAttribute), true))
            {
                CustomAttribute attribute = (CustomAttribute)property.GetCustomAttribute(typeof(CustomAttribute), true);
                Console.WriteLine($"{attribute.Description}_{attribute.Remark}");
                attribute.Show();
            }
            #endregion

            #region 獲取Answer()方法上面定義的特性
            // 獲取Answer方法
            MethodInfo method = type.GetMethod("Answer");
            if (method.IsDefined(typeof(CustomAttribute), true))
            {
                CustomAttribute attribute = (CustomAttribute)method.GetCustomAttribute(typeof(CustomAttribute), true);
                Console.WriteLine($"{attribute.Description}_{attribute.Remark}");
                attribute.Show();
            }
            #endregion

            #region 獲取參數定義的特性
            ParameterInfo parameter = method.GetParameters()[0];
            if (parameter.IsDefined(typeof(CustomAttribute), true))
            {
                CustomAttribute attribute = (CustomAttribute)parameter.GetCustomAttribute(typeof(CustomAttribute), true);
                Console.WriteLine($"{attribute.Description}_{attribute.Remark}");
                attribute.Show();
            }
            #endregion

            #region 獲取返回值定義的特性
            ParameterInfo returnParameter = method.ReturnParameter;
            if (returnParameter.IsDefined(typeof(CustomAttribute), true))
            {
                CustomAttribute attribute = (CustomAttribute)returnParameter.GetCustomAttribute(typeof(CustomAttribute), true);
                Console.WriteLine($"{attribute.Description}_{attribute.Remark}");
                attribute.Show();
            }
            #endregion

            string result = student.Answer("Tom");
            Console.WriteLine(result);
        }
    }
}

Main()方法里面調用:

using MyAttribute.Extension;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyAttribute
{
    class Program
    {
        static void Main(string[] args)
        {
            Student student = new Student();
            student.Id = 123;
            student.Name = "time";
            // 使用Manager類管理Student
            Manager.Show(student);

            Console.ReadKey();
        }
    }
}

結果:

C#特性怎么定義

四、應用特性

場景一:用戶狀態的枚舉值,定義的是英文的字段,需要輸出中文含義。枚舉定義如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyAttribute.Extension
{
    /// <summary>
    /// 枚舉類型 用戶狀態
    /// </summary>
    public enum UserState
    {
        /// <summary>
        /// 正常
        /// </summary>
        Normal = 0,
        /// <summary>
        /// 凍結
        /// </summary>
        Frozen = 1,

        /// <summary>
        /// 刪除
        /// </summary>
        Deleted = 2
    }
}

普通做法:根據枚舉值進行判斷,然后輸出中文含義:

UserState userState = UserState.Normal;
switch(userState)
{
        case UserState.Normal:
                 Console.WriteLine("正常");
                 break;
        case UserState.Frozen:
                 Console.WriteLine("凍結");
                 break;
        case UserState.Deleted:
                 Console.WriteLine("刪除");
                 break;
}

這種寫法違反開不原則,不利于以后的擴展,下面使用特性實現。

先定義Remark特性:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;

namespace MyAttribute.Extension
{
    /// <summary>
    /// RemarkAttribute 特性
    /// </summary>
    public class RemarkAttribute  :Attribute
    {
        private string _Remark = null;
        /// <summary>
        /// 有參構造
        /// </summary>
        /// <param name="remark"></param>
        public RemarkAttribute(string remark)
        {
            this._Remark = remark;
        }

        public string GetRemark()
        {
            return _Remark;
        }
    }
}

UserState枚舉修改如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyAttribute.Extension
{
    /// <summary>
    /// 枚舉類型 用戶狀態
    /// </summary>
    public enum UserState
    {
        /// <summary>
        /// 正常
        /// </summary>
        [Remark("正常")]
        Normal = 0,
        /// <summary>
        /// 凍結
        /// </summary>
        [Remark("凍結")]
        Frozen = 1,

        /// <summary>
        /// 刪除
        /// </summary>
        [Remark("刪除")]
        Deleted = 2
    }
}

對Enum類型進行擴展:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace MyAttribute.Extension
{
    public static class EnumExtension
    {
        /// <summary>
        /// Enum的擴展方法,靜態類、靜態方法 第一個參數前面添加this關鍵字
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string GetRemark(this Enum value)
        {
            // 獲取類型
            Type type = value.GetType();
            // 獲取字段
            FieldInfo field = type.GetField(value.ToString());
            // 判斷字段上面是否定義了RemarkAttribute特性
            if (field.IsDefined(typeof(RemarkAttribute)))
            {
                // 創建實例
                RemarkAttribute attribute = (RemarkAttribute)field.GetCustomAttribute(typeof(RemarkAttribute));
                // 返回RemarkAttribute特性里面的GetRemark()方法
                return attribute.GetRemark();
            }
            else
            {
                return value.ToString();
            }
        }
    }
}

Main()方法里面調用:

using MyAttribute.Extension;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyAttribute
{
    class Program
    {
        static void Main(string[] args)
        {
            Student student = new Student();
            student.Id = 123;
            student.Name = "time";
            // 使用Manager類管理Student
            //Manager.Show(student);


            UserState userState = UserState.Normal;
            //switch(userState)
            //{
            //    case UserState.Normal:
            //        Console.WriteLine("正常");
            //        break;
            //    case UserState.Frozen:
            //        Console.WriteLine("凍結");
            //        break;
            //    case UserState.Deleted:
            //        Console.WriteLine("刪除");
            //        break;
            //}
            Console.WriteLine(userState.GetRemark());
            Console.ReadKey();
        }
    }
}

結果:

C#特性怎么定義

場景二、做數據校驗

Student中有QQ這個屬性,范圍是10000-999999999999,校驗QQ屬性的值在這個范圍區間內。

1、定義一個RangeAttribute特性,用來驗證屬性范圍
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyAttribute.Extension
{
    /// <summary>
    /// 定義LongAttribute特性,并且特性只能應用在字段和屬性上面
    /// </summary>
    [AttributeUsage(AttributeTargets.Field|AttributeTargets.Property)]
    public class RangeAttribute :Attribute
    {
        /// <summary>
        /// 最小范圍
        /// </summary>
        private long _MinRange = 0;

        /// <summary>
        /// 最大范圍
        /// </summary>
        private long _MaxRange = 0;

        public RangeAttribute(long min,long max)
        {
            this._MinRange = min;
            this._MaxRange = max;
        }

        /// <summary>
        /// 檢查屬性范圍
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool Check(object value)
        {
            if(value!=null && !string.IsNullOrWhiteSpace(value.ToString()))
            {
                if(long.TryParse(value.ToString(),out long IResult))
                {
                    if(IResult>this._MinRange && IResult<this._MaxRange)
                    {
                        return true;
                    }
                }
            }

            return false;
        }
    }
}
2、在Student類的QQ屬性上面應用特性
[Range(10001,999999999999)]
public long QQ { get; set; }
3、對Object類型進行擴展
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace MyAttribute.Extension
{
    /// <summary>
    /// object類型的驗證擴展
    /// </summary>
    public static class ObjectExtension
    {
        /// <summary>
        /// 對object類型擴展一個Validate的方法
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="msg">輸出參數,輸出驗證信息。如果驗證通過,輸出空字符串;如果驗證不通過,輸出具體信息</param>
        /// <returns></returns>
        public static bool Validate(this object obj,out string msg)
        {
            // 獲取類型
            Type type = obj.GetType();
            // 獲取屬性
            PropertyInfo[] propertyInfos= type.GetProperties();
            foreach(PropertyInfo prop in propertyInfos)
            {
                if(prop.IsDefined(typeof(LongAttribute)))
                {
                    LongAttribute attribute = (LongAttribute)prop.GetCustomAttribute(typeof(LongAttribute));
                    if(!attribute.Check(prop.GetValue(obj)))
                    {
                        msg = prop.Name + "檢查失敗";
                        return false;
                    }
                }
            }
            msg = "";
            return true;

        }
    }
}
4、在Manager類里面使用Validate擴展方法
// 驗證
string msg = string.Empty;
bool tfResult=  student.Validate(out msg);
if(!tfResult)
{
      Console.WriteLine(msg);
}
5、在Main()方法里面調用
Student student = new Student();
student.Id = 123;
student.Name = "time";
student.QQ = 9999;
// 使用Manager類管理Student
Manager.Show(student);

結果:

C#特性怎么定義

如果這時候Student里面增加了Name屬性,并且要驗證Name屬性的長度,這時需要增加一個驗證屬性長度的特性:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyAttribute.Extension
{
    /// <summary>
    ///  驗證長度的特性,只能應用于字段和屬性上面
    /// </summary>
    [AttributeUsage(AttributeTargets.Field|AttributeTargets.Property)]
    public class LengthAttribute:Attribute
    {
        /// <summary>
        /// 最小長度
        /// </summary>
        private int _MinLength = 0;

        /// <summary>
        /// 最大長度
        /// </summary>
        private int _MaxLength = 0;

        public LengthAttribute(int min, int max)
        {
            this._MinLength = min;
            this._MaxLength = max;
        }

        /// <summary>
        /// 檢查屬性長度
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool Check(object value)
        {
            if (value != null && !string.IsNullOrWhiteSpace(value.ToString()))
            {
                if (long.TryParse(value.ToString(), out long IResult))
                {
                    if (IResult > this._MinLength && IResult < this._MaxLength)
                    {
                        return true;
                    }
                }
            }

            return false;
        }
    }
}

在Student類的Name屬性上面應用LengthAttribute特性:

[Length(5,10)]
public string Name { get; set; }

在ObjectExtension里面增加長度的驗證:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace MyAttribute.Extension
{
    /// <summary>
    /// object類型的驗證擴展
    /// </summary>
    public static class ObjectExtension
    {
        /// <summary>
        /// 對object類型擴展一個Validate的方法
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="msg">輸出參數,輸出驗證信息。如果驗證通過,輸出空字符串;如果驗證不通過,輸出具體信息</param>
        /// <returns></returns>
        public static bool Validate(this object obj,out string msg)
        {
            // 獲取類型
            Type type = obj.GetType();
            // 獲取屬性
            PropertyInfo[] propertyInfos= type.GetProperties();
            foreach(PropertyInfo prop in propertyInfos)
            {
                // 檢查屬性上面是否定義了RangeAttribute特性
                if (prop.IsDefined(typeof(RangeAttribute)))
                {
                    RangeAttribute attribute = (RangeAttribute)prop.GetCustomAttribute(typeof(RangeAttribute));
                    if(!attribute.Check(prop.GetValue(obj)))
                    {
                        msg = string.Format($"屬性{ prop.Name}范圍檢查失敗");
                        return false;
                    }
                }

                // 檢查屬性上面是否定義了LengthAttribute特性
                if (prop.IsDefined(typeof(LengthAttribute)))
                {
                    LengthAttribute attribute = (LengthAttribute)prop.GetCustomAttribute(typeof(LengthAttribute));
                    if (!attribute.Check(prop.GetValue(obj)))
                    {
                        msg = string.Format($"屬性{ prop.Name}長度檢查失敗");
                        return false;
                    }
                }
            }
            msg = "";
            return true;

        }
    }
}

最后在Main()方法里面調用:

Student student = new Student();
student.Id = 123;
student.Name = "time";
// 使用Manager類管理Student
Manager.Show(student);

結果:

C#特性怎么定義

仔細查看ObjectExtension擴展類:每增加一個特性,擴展方法里面就要增加一段相同的代碼(只是特性的類型不同),那么能不能做到增加特性,而這里不需要修改呢?請看下面的修改:

1、定義一個抽象類繼承自Attribute,里面有一個抽象的Check()方法,定義如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyAttribute.Extension
{
    /// <summary>
    /// 抽象基類,繼承自Attribute
    /// </summary>
    public abstract class AbstractValidateAttribute:Attribute
    {
        public abstract bool Check(object value);
    }
}
2、修改RangeAttribute和LengthAttribute兩個特性類,都繼承自AbstractValidateAttribute基類

RangeAttribute類:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyAttribute.Extension
{
    /// <summary>
    /// 定義LongAttribute特性,并且特性只能應用在字段和屬性上面
    /// </summary>
    [AttributeUsage(AttributeTargets.Field|AttributeTargets.Property)]
    public class RangeAttribute : AbstractValidateAttribute
    {
        /// <summary>
        /// 最小范圍
        /// </summary>
        private long _MinRange = 0;

        /// <summary>
        /// 最大范圍
        /// </summary>
        private long _MaxRange = 0;

        public RangeAttribute(long min,long max)
        {
            this._MinRange = min;
            this._MaxRange = max;
        }

        /// <summary>
        /// 重寫基類方法 檢查屬性范圍
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public override bool Check(object value)
        {
            if(value!=null && !string.IsNullOrWhiteSpace(value.ToString()))
            {
                if(long.TryParse(value.ToString(),out long IResult))
                {
                    if(IResult>this._MinRange && IResult<this._MaxRange)
                    {
                        return true;
                    }
                }
            }

            return false;
        }
    }
}

LengthAttribute類:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyAttribute.Extension
{
    /// <summary>
    ///  驗證長度的特性,只能應用于字段和屬性上面
    /// </summary>
    [AttributeUsage(AttributeTargets.Field|AttributeTargets.Property)]
    public class LengthAttribute: AbstractValidateAttribute
    {
        /// <summary>
        /// 最小長度
        /// </summary>
        private int _MinLength = 0;

        /// <summary>
        /// 最大長度
        /// </summary>
        private int _MaxLength = 0;

        public LengthAttribute(int min, int max)
        {
            this._MinLength = min;
            this._MaxLength = max;
        }

        /// <summary>
        /// 重寫基類方法 檢查屬性長度
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public override bool Check(object value)
        {
            if (value != null && !string.IsNullOrWhiteSpace(value.ToString()))
            {
                if (long.TryParse(value.ToString(), out long IResult))
                {
                    if (IResult > this._MinLength && IResult < this._MaxLength)
                    {
                        return true;
                    }
                }
            }
            return false;
        }
    }
}
3、修改ObjectExtension擴展類
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace MyAttribute.Extension
{
    /// <summary>
    /// object類型的驗證擴展
    /// </summary>
    public static class ObjectExtension
    {
        /// <summary>
        /// 對object類型擴展一個Validate的方法
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="msg">輸出參數,輸出驗證信息。如果驗證通過,輸出空字符串;如果驗證不通過,輸出具體信息</param>
        /// <returns></returns>
        public static bool Validate(this object obj,out string msg)
        {
            // 獲取類型
            Type type = obj.GetType();
            // 獲取屬性
            PropertyInfo[] propertyInfos= type.GetProperties();
            foreach(PropertyInfo prop in propertyInfos)
            {
                // 判斷屬性上面是否定義了AbstractValidateAttribute特性
                if (prop.IsDefined(typeof(AbstractValidateAttribute),true))
                {
                    // 屬性上面可能會定義多個特性,所以這里使用數組
                    object[] attributeArray = prop.GetCustomAttributes(typeof(AbstractValidateAttribute), true);
                    foreach(AbstractValidateAttribute attribute in attributeArray)
                    {
                        if (!attribute.Check(prop.GetValue(obj)))
                        {
                            msg = string.Format($"屬性{ prop.Name}檢查失敗");
                            return false;
                        }
                    }
                }

                //// 檢查屬性上面是否定義了RangeAttribute特性
                //if (prop.IsDefined(typeof(RangeAttribute)))
                //{
                //    RangeAttribute attribute = (RangeAttribute)prop.GetCustomAttribute(typeof(RangeAttribute));
                //    if(!attribute.Check(prop.GetValue(obj)))
                //    {
                //        msg = string.Format($"屬性{ prop.Name}范圍檢查失敗");
                //        return false;
                //    }
                //}

                //// 檢查屬性上面是否定義了LengthAttribute特性
                //if (prop.IsDefined(typeof(LengthAttribute)))
                //{
                //    LengthAttribute attribute = (LengthAttribute)prop.GetCustomAttribute(typeof(LengthAttribute));
                //    if (!attribute.Check(prop.GetValue(obj)))
                //    {
                //        msg = string.Format($"屬性{ prop.Name}長度檢查失敗");
                //        return false;
                //    }
                //}
            }
            msg = "";
            return true;

        }
    }
}
4、運行結果:

C#特性怎么定義

經過上面的修改以后,如果以后要新增一個特性,那么該特性只需要在本類中重寫基類的Check()方法即可,而不需要在修改ObjectExtension擴展類。

到此,相信大家對“C#特性怎么定義”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節
推薦閱讀:
  1. C#特性
  2. C# 語言特性

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

彭阳县| 仁怀市| 昭苏县| 乃东县| 东丰县| 蕲春县| 潜山县| 招远市| 云安县| 佛学| 泸定县| 新乡县| 会东县| 普陀区| 莱芜市| 临桂县| 潍坊市| 和硕县| 云南省| 宝丰县| 安龙县| 定陶县| 维西| 将乐县| 宜昌市| 葫芦岛市| 丰台区| 镇巴县| 平凉市| 临高县| 呼伦贝尔市| 饶平县| 溧阳市| 德兴市| 黄冈市| 济源市| 高邮市| 大连市| 凤翔县| 福州市| 皋兰县|