C# 进阶 特性

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

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

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

 

 


泛型:把类型做到通用--》代表着动态
 反射:读取DLL文件描述信息的一个类库
特性:贴标签--贴上标签就产生了新功能


进阶语法--》特性:他就是一类,继承自Attribute,如果是的话他就是特性

目前那些地方使用到了特性:几乎所有框架都用到了,MVC---WebApi--EF--IOC--AOP
特性使用场景:可以用来做数据验证

特性分类 :
一、系统自带特性(DebuggerStepThrough、Obsolete)有一些是影响到了编译器的运行
二、自定义

 

特性的创建和调用(利用反射)

class AttribteTest
    {
        public void Test()
        {
            Type type = typeof(UseAttibute);
            object[] customAttributes = type.GetCustomAttributes(true);
            foreach (object customAttribute in customAttributes)
            {
                DefindAttribute defindAttribute = customAttribute as DefindAttribute;
                if (defindAttribute!=null)
                {
                    Console.WriteLine(defindAttribute.ShowInfo);
                }
            }
        }
    }
 


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

    public class DefindAttribute : Attribute
    {
        public DefindAttribute(string showInfo)
        {
            ShowInfo = showInfo;
        }

        public string ShowInfo { get; set; }
    }

 特性实验1

namespace CSharpAdvancedAttribute.EnumExtend
{

    [AttributeUsage(AttributeTargets.Field)]
   public class RemarkAttribute:Attribute
    {
        /// <summary>
        /// 状态特性
        /// </summary>
        /// <param name="remark"></param>
        public RemarkAttribute(string remark)
        {
            this.Remark = remark;
        }
        public string Remark { get; private set; }
    }
}

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


namespace CSharpAdvancedAttribute.EnumExtend
{
   public class AttributeInvoke
    {
        public string GetRemark( UserState userState)
        {
            Type type = userState.GetType();
            var fileId = type.GetField(userState.ToString());
            if (fileId.IsDefined(typeof(RemarkAttribute),true))
            {
                RemarkAttribute remarkAttribute=(RemarkAttribute)fileId.GetCustomAttribute(typeof(RemarkAttribute), true);
                return remarkAttribute.Remark;
            }
            else
            {
                return userState.ToString();
            }
        }
    }
}

//实验一
            UserState userState = UserState.Frozen;
            if (userState == UserState.Normal)
            {
                Console.WriteLine("正常");
            }
            else if (userState == UserState.Frozen)
            {
                Console.WriteLine("冻结");
            }

      //通过特性来操作
        AttributeInvoke attributeInvoke = new AttributeInvoke();
        Console.WriteLine(attributeInvoke.GetRemark(userState));

 

特性实验2

namespace CSharpAdvancedAttribute.ShowExtend
{
    [AttributeUsage(AttributeTargets.All,AllowMultiple =true,Inherited =true)]
   public class ShowAttribute:Attribute
    {
        public string ShowInfo { get; set; }
        public void Show()
        {
            Console.WriteLine(ShowInfo);
        }
    }
}

namespace CSharpAdvancedAttribute.ShowExtend
{
    [Show(ShowInfo ="我是在类上的特性")]
    [Show(ShowInfo = "我是在类上的第二个特性")]
    public class ShowTest
    {
        [Show(ShowInfo = "我是在方法上的特性")]
        public void TestMethod()
        {

        }
        [Show(ShowInfo = "我是在属性上的特性")]
        public string TestProperty { get; set; }

        [Show(ShowInfo = "我是在字段上的特性")]
        public string TestFiled;
    }
}

namespace CSharpAdvancedAttribute.ShowExtend
{
   public static class InvokeConter
    {
        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[] attributeMethods = method.GetCustomAttributes(typeof(ShowAttribute), true);
                        foreach (ShowAttribute attribute in attributeMethods)
                        {
                            attribute.Show();
                        }
                    }
                }

                //在属性上查找
                foreach (PropertyInfo property in type.GetProperties())
                {
                    if (property.IsDefined(typeof(ShowAttribute), true))
                    {
                        object[] attributeProperty = property.GetCustomAttributes(typeof(ShowAttribute), true);
                        foreach (ShowAttribute attribute in attributeProperty)
                        {
                            attribute.Show();
                        }
                    }
                }

                //在字段上查找
                foreach (FieldInfo field in type.GetFields())
                {
                    if (field.IsDefined(typeof(ShowAttribute), true))
                    {
                        object[] attributeField = field.GetCustomAttributes(typeof(ShowAttribute), true);
                        foreach (ShowAttribute attribute in attributeField)
                        {
                            attribute.Show();
                        }
                    }
                }


            }
        }

    }
}


            ////实验二
            //1--普通方式
            //ShowTest showTest = new ShowTest();
            //InvokeConter invokeConter = new InvokeConter();
            //invokeConter.InvokeManager(showTest);
            //2-扩展方法
            ShowTest showTest = new ShowTest();
            showTest.InvokeManager();

特性实验3(特性验证)

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

namespace CSharpAdvancedAttribute.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;
        }
    }
}

namespace CSharpAdvancedAttribute.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;
        }
    }
}

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

namespace CSharpAdvancedAttribute.ValidateExtend
{
    [AttributeUsage(AttributeTargets.Property)]
    public class StringLengthAttribute : AbstractValidateAttribute
    {
        private int _Mni=0;
        private int _Max = 0;

        public StringLengthAttribute(int min,int max)
        {
            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 CSharpAdvancedAttribute.ValidateExtend
{
   public class Student
    {
        public int Id { get; set; }
        [Required]
        [StringLength(5,10)]
        public string StudentName { get; set; }
        [Required]
        [Long(11)]
        public long PoneNumber { get; set; }
    }
}
/实验三(特性验证)
            Student student = new Student()
            {
                Id = 1,
                PoneNumber = 12345678900,
                StudentName = "Ant"
            };

            if (student.Validate())
            {
                Console.WriteLine("验证成功");
            }
            else
            {
                Console.WriteLine("验证成功");
            }

 

posted @ 2021-02-28 21:50  KnowledgePorter  阅读(20)  评论(0)    收藏  举报