C#特性 Attribute

特性:记忆是一个类,继承自Attribute,如果是的话,它就是特性

特性的继承

using System.Runtime.InteropServices;

namespace System.Diagnostics
{
    //
    // 摘要:
    //     指示调试器逐句通过代码,而不是单步执行代码。 无法继承此类。
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method, Inherited = false)]
    [ComVisible(true)]
    public sealed class DebuggerStepThroughAttribute : Attribute
    {
        //
        // 摘要:
        //     初始化 System.Diagnostics.DebuggerStepThroughAttribute 类的新实例。
        public DebuggerStepThroughAttribute();
    }
}

示例如下:

using System;
using System.Diagnostics;

namespace AdvancedAttribute
{
    class Program
    {
        static void Main(string[] args)
        {
            UseAttributeClass useAttributeClass = new UseAttributeClass();
            useAttributeClass.DoMethod();
            Console.ReadKey();
        }
    }

    public class UseAttributeClass
    {
        //举例适应的特性[DebuggerStepThrough]
        [DebuggerStepThrough]
        public void DoMethod()
        {
            Console.WriteLine("这个方法很简单");
        }
    }
}

特性使用场景:可以用来做数据验证

 public class ResetPasswordViewModel
    {
        [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; }

        public string Code { get; set; }
    }

    public class ForgotPasswordViewModel
    {
        [Required]
        [EmailAddress]
        [Display(Name = "电子邮件")]
        public string Email { get; set; }
    }

目标:学会后要做一个O/RM框架

 [Authorize]
    public class AccountController : Controller
    {
        private ApplicationSignInManager _signInManager;
        private ApplicationUserManager _userManager;

        public AccountController()
        {
        }
    }

使用场景

类 Attribute 将预定义的系统信息或用户定义的自定义信息与目标元素相关联。 目标元素可以是程序集、类、构造函数、委托、枚举、事件、字段、接口、方法、可移植可执行文件模块、参数、属性、返回值、结构或其他属性。

属性提供的信息也称为元数据。 应用程序可以在运行时检查元数据,以控制程序处理数据的方式,或在运行时由外部工具控制应用程序本身的处理和维护方式之前。 例如,.NET 预定义并使用属性类型来控制运行时行为,某些编程语言使用属性类型来表示 .NET 通用类型系统不直接支持的语言功能。

所有属性类型都直接或间接派生自 Attribute 类。 属性可以应用于任何目标元素;多个属性可以应用于同一目标元素;和属性可由派生自目标元素的元素继承。 使用 AttributeTargets 类指定应用属性的目标元素。

目前哪些地方使用到了特性:几乎所有的框架都用到了 MVC-- WebApi --EF–IOC–AOP

特性分类:

                      一,系统自带特性 DebuggerStepThrough,Obsolete等等有一些是影响到了编译器的运行
                      二,自定义

特性的创建 特性:贴标签–贴上标签就产生了新的功能

特性看成类

using System;

namespace AdvancedAttribute1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("---------------------创建特性----------------------");
            AttributeTest attributeTest = new AttributeTest();
            attributeTest.Test();
            Console.ReadKey();
        }
    }
    #region 创建特性
    class AttributeTest
    {
        public void Test()
        {
            Type type = typeof(UseAttribute);
            object[] customAttributes = type.GetCustomAttributes(true);
            foreach (object customAttribute in customAttributes)
            {
                DefindAttribute defindAttribute = customAttribute as DefindAttribute;
                if (defindAttribute != null)
                {
                    Console.WriteLine(defindAttribute.ShowInfo);
                }
            }
        }
    }

    [Defind("这是第一个特性的创建!")]
    class UseAttribute
    {

    }
    class DefindAttribute : Attribute
    {
        public DefindAttribute(string showInfo)
        {
            ShowInfo = showInfo;
        }
        public string ShowInfo { get; set; }
    }
    #endregion
}

C#特性 Attribute_第1张图片

特性试验一

using AdvancedAttribute2.EnumExtend;
using System;

namespace AdvancedAttribute2
{
    class Program
    {
        static void Main(string[] args)
        {
            //实验一
            UserState userState = UserState.Frozen;
            if (userState == UserState.Normal)
            {
                Console.WriteLine("正常");
            }
            else if (userState == UserState.Frozen)
            {
                Console.WriteLine("冻结");
            }
            else if (userState == UserState.Delete)
            {
                Console.WriteLine("删除");
            }
            //通过特性来操作
            Console.WriteLine("--------------------通过特性来操作--------------------");
            AttributeInvoke attributeInvoke = new AttributeInvoke();
            Console.WriteLine(attributeInvoke.GetRemark(userState));
            Console.ReadKey();
        }
    }
}

using System;
using System.Reflection;

namespace AdvancedAttribute2.EnumExtend
{
    public class AttributeInvoke
    {
        public string GetRemark(UserState userState)
        {
            Type type = userState.GetType();
            var fileId = type.GetField(userState.ToString());
            //true 可以进行查找子类
            if (fileId.IsDefined(typeof(RemarkAttribute), true))
            {
                RemarkAttribute remarkAttribute = (RemarkAttribute)fileId.GetCustomAttribute(typeof(RemarkAttribute), true);
                return remarkAttribute.Remark;
            }
            else
            {
                return userState.ToString();
            }
        }
    }
}

using System;

namespace AdvancedAttribute2.EnumExtend
{
    /// 
    /// 特性上面也可以添加特性 
    /// 
    [AttributeUsage(AttributeTargets.Field,AllowMultiple =true)]//标记在字段上
    public class RemarkAttribute : Attribute
    {
        /// 
        /// 状态特性
        /// 
        /// 
        public RemarkAttribute(string remark)
        {
            this.Remark = remark;
        }
        public string Remark { get; set; }//属性
    }
}

namespace AdvancedAttribute2.EnumExtend
{
    public enum UserState
    {
        /// 
        /// 正常
        /// 
        [Remark("正常")]
        Normal = 0,
        /// 
        /// 冻结
        /// 
        [Remark("冻结")]
        Frozen = 1,
        /// 
        /// 删除
        /// 
        [Remark("删除")]
        Delete = 2
    }
}

C#特性 Attribute_第2张图片

特性三大步:

             第一步--定义特性
             第二步--标记
             第三步--调用
namespace AdvancedAttribute2.ShowExtend
{
    [Show(ShowInfo = "我是在类上的特性")]
    [Show(ShowInfo = "我是在类上的第二个特性")]
    public class ShowTest
    {
        [Show(ShowInfo = "我是在方法上的特性")]
        public void Test()
        { }
        [Show(ShowInfo = "我是在属性上的特性---------")]
        public string TestProperty { get; set; }//属性
        [Show(ShowInfo = "我是在字段上的特性========")]
        public string TestFiled;//字段
    }
}

using System;

namespace AdvancedAttribute2.ShowExtend
{
    [AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = true)]//所有的地方都可以使用|多重标记
    public class ShowAttribute : Attribute
    {
        public string ShowInfo { get; set; }
        public void Show()
        {
            Console.WriteLine(ShowInfo);
        }
    }
}

普通写法

using System;
using System.Reflection;

namespace AdvancedAttribute2.ShowExtend
{
    public class InvokeConter
    {
        public void InvokeManager<T>(T showTest) where T : new()
        {
            Type type = showTest.GetType();//获取类型
            if (type.IsDefined(typeof(ShowAttribute), true))
            {
                //在类上面查找特性
                object[] attributes = type.GetCustomAttributes(typeof(ShowAttribute), true);
                foreach (ShowAttribute attribute in attributes)
                {
                    attribute.Show();
                }
                //在方法上查找
                foreach (MethodInfo method in type.GetMethods())
                {
                    if (method.IsDefined(typeof(ShowAttribute), true))
                    {
                        object[] attributeMethodInfos = method.GetCustomAttributes(typeof(ShowAttribute), true);
                        foreach (ShowAttribute attribute in attributeMethodInfos)
                        {
                            attribute.Show();
                        }
                    }
                }
                //在属性上查找
                foreach (PropertyInfo propertyInfo in type.GetProperties())
                {
                    if (propertyInfo.IsDefined(typeof(ShowAttribute), true))
                    {
                        object[] attributePropertyInfos = propertyInfo.GetCustomAttributes(typeof(ShowAttribute), true);
                        foreach (ShowAttribute attribute in attributePropertyInfos)
                        {
                            attribute.Show();
                        }
                    }
                }
                //在字段上查找
                foreach (FieldInfo fieldInfo in type.GetFields())
                {
                    if (fieldInfo.IsDefined(typeof(ShowAttribute), true))
                    {
                        object[] attributefieldInfos = fieldInfo.GetCustomAttributes(typeof(ShowAttribute), true);
                        foreach (ShowAttribute attribute in attributefieldInfos)
                        {
                            attribute.Show();
                        }
                    }
                }
            }
        }
    }
}

扩展写法

using System;
using System.Reflection;

namespace AdvancedAttribute2.ShowExtend
{
    public static class InvokeConterKuoZhang
    {
        public static void InvokeManager<T>(this T showTest) where T : new()
        {
            Type type = showTest.GetType();//获取类型
            if (type.IsDefined(typeof(ShowAttribute), true))
            {
                //在类上面查找特性
                object[] attributes = type.GetCustomAttributes(typeof(ShowAttribute), true);
                foreach (ShowAttribute attribute in attributes)
                {
                    attribute.Show();
                }
                //在方法上查找
                foreach (MethodInfo method in type.GetMethods())
                {
                    if (method.IsDefined(typeof(ShowAttribute), true))
                    {
                        object[] attributeMethodInfos = method.GetCustomAttributes(typeof(ShowAttribute), true);
                        foreach (ShowAttribute attribute in attributeMethodInfos)
                        {
                            attribute.Show();
                        }
                    }
                }
                //在属性上查找
                foreach (PropertyInfo propertyInfo in type.GetProperties())
                {
                    if (propertyInfo.IsDefined(typeof(ShowAttribute), true))
                    {
                        object[] attributePropertyInfos = propertyInfo.GetCustomAttributes(typeof(ShowAttribute), true);
                        foreach (ShowAttribute attribute in attributePropertyInfos)
                        {
                            attribute.Show();
                        }
                    }
                }
                //在字段上查找
                foreach (FieldInfo fieldInfo in type.GetFields())
                {
                    if (fieldInfo.IsDefined(typeof(ShowAttribute), true))
                    {
                        object[] attributefieldInfos = fieldInfo.GetCustomAttributes(typeof(ShowAttribute), true);
                        foreach (ShowAttribute attribute in attributefieldInfos)
                        {
                            attribute.Show();
                        }
                    }
                }
            }
        }
    }
}


            Console.WriteLine("--------------------实验二普通方式--------------------");
            ShowTest showTest = new ShowTest();
            InvokeConter invokeConter = new InvokeConter();
            invokeConter.InvokeManager(showTest);
            Console.WriteLine("--------------------实验二扩展方法--------------------");
            ShowTest showTest1 = new ShowTest();
            showTest1.InvokeManager();

C#特性 Attribute_第3张图片
实验三 扩展方法实现

using System;

namespace AdvancedAttribute2.ValidateExtend
{
    public abstract class AbstractValidateAttribute : Attribute
    {
        public abstract bool Validate(object Value);
    }
}

using System;

namespace AdvancedAttribute2.ValidateExtend
{
    public static class AttributeExtend
    {
        public static bool Validate<T>(this T t)
        {
            Type type = t.GetType();
            //属性的验证
            foreach (var property in type.GetProperties())
            {
                if (property.IsDefined(typeof(AbstractValidateAttribute), true))
                {
                    object objValue = property.GetValue(t);
                    foreach (AbstractValidateAttribute attribute in property.GetCustomAttributes(typeof(AbstractValidateAttribute), true))
                    {
                        if (!attribute.Validate(objValue)) //如果成功了之后继续验证,否则直接返回
                        {
                            return false;
                        }
                    }
                }
            }
            return true;
        }
    }
}

using System;

namespace AdvancedAttribute2.ValidateExtend
{
    [AttributeUsage(AttributeTargets.Property)]
    public class LongAttribute : AbstractValidateAttribute
    {
        private long _Long = 0;
        public LongAttribute(long phoneLength)
        {
            this._Long = phoneLength;
        }
        public override bool Validate(object objValue)
        {
            return objValue != null && objValue.ToString().Length == 11;
        }
    }
}

using System;

namespace AdvancedAttribute2.ValidateExtend
{
    [AttributeUsage(AttributeTargets.Property)]
    public class RequiredAttribute : AbstractValidateAttribute
    {
        public override bool Validate(object objValue)
        {
            return objValue != null && !string.IsNullOrWhiteSpace(objValue.ToString());
        }
    }
}

using System;

namespace AdvancedAttribute2.ValidateExtend
{
    [AttributeUsage(AttributeTargets.Property)]
    public class StringLengthAttribute : AbstractValidateAttribute
    {
        private int _Mni = 0;
        private int _Max = 0;
        public StringLengthAttribute(int max, int min)
        {
            this._Max = max;
            this._Mni = min;
        }
        public override bool Validate(object objValue)
        {
            return objValue != null && objValue.ToString().Length > this._Mni && objValue.ToString().Length < this._Max;
        }
    }
}

namespace AdvancedAttribute2.ValidateExtend
{
    public class Student
    {
        public int Id { get; set; }
        [Required]
        [StringLength(10, 5)]
        public string StudentName { get; set; }
        [Required]
        [Long(11)]
        public long PhoneNumber { get; set; }
    }
}

在这里插入图片描述
代码示例
https://github.com/KuKuDePerson/CSharpAdvancedAttribute

你可能感兴趣的:(C#,c#)