C# 特性(Attribute)

24 篇文章 0 订阅

C# 特性(Attribute)

特性(Attribute)是用于在运行时传递程序中各种元素(比如类、方法、结构、枚举、组件等)的行为信息的声明性标签。您可以通过使用特性向程序添加声明性信息。一个声明性标签是通过放置在它所应用的元素前面的方括号([ ])来描述的。

特性(Attribute)用于添加元数据,如编译器指令和注释、描述、方法、类等其他信息。.Net 框架提供了两种类型的特性:预定义特性和自定义特性。

添加特性之后会在对应的位置添加特性中的代码,我们是看不到的,通过反编译查看IL中间语言可以查看。

特性是需要主动调用才会生效,像MVC,EF中的特性是因为官方写好了,我们直接用。

特性的使用:

1.Obsolete:用于声明方法过时

// 使用时提示方法过时警告
	[Obsolete("该方法已经过时")]
	// 使用时提示方法错误,直接报错
	//[Obsolete("该方法已经过时,直接报错",true)]
	public void ObsoleteDemo()
	{
	
	}
	
	// 调用
	Demo demo = new Demo();
    demo.ObsoleteDemo();
    // 或发现demo.ObsoleteDemo(); 绿色波浪线提示方法已过时

2.自定义特性在不同位置的使用:

	// [Custom]等同于 [Custom()]:标识执行无参数的构造
    // 但是一般同时写会出错,提示特性重复,解决方法:在对用的特性类里面添加:			[AttributeUsage(AttributeTargets.All,AllowMultiple =true)] 即可
    //[Custom] 
    // [Custom(123)]:表示有参数的构造函数
    [Custom(123, Description = "类上的特性", Remark = "类上的特性")]
    public class Student
    {
        // 无参数的构造函数
        [Custom(Description = "属性上的特性", Remark = "属性上的特性")]
        public int Id { get; set; }

        public string Name { get; set; }

        [Custom(Description = "方法上的特性", Remark = "方法上的特性")]
        public void Study()
        {
            Console.WriteLine($"这里是{this.Name}跟着Eleven老师学习");
        }

        [Custom(Description = "方法上的特性", Remark = "方法上的特性")]
        [return: Custom(Description = "返回值上的特性", Remark = "返回值上的特性")]
        public string Answer([Custom(Description = "方法上的参数的特性", Remark = "方法上的参数的特性")] string name)
        {
            return $"This is {name}";
        }
    }

	// 关于上述Student实体类各种特性的调用方法:
	public static void Show(Student student)
    {
        Console.WriteLine($"-------------------获取特性-------------------");
        Type type = typeof(Student);
        // 或者  student.GetType();

        #region 类上面的特性
        {
            Console.WriteLine($"-------------------类上面的特性-------------------");
            // 查找是否有指定的特性
            if (type.IsDefined(typeof(CustomAttribute), true))
            {
                // 如果有,获取特性
                // 这句话其实就是去执行 CustomAttribute 类的 构造函数 字段。。。
                object aAttribute = type.GetCustomAttribute(typeof(CustomAttribute), true);
                // 将找到的转化为 CustomAttribute 类型的attribute
                CustomAttribute customAttribute = (CustomAttribute)aAttribute;

                Console.WriteLine($"{customAttribute.Description}_{customAttribute.Remark}");

                // 通过反射执行特性类中的方法
                customAttribute.Show();
            }
        }
        #endregion

        #region 参数上的特性
        {
            Console.WriteLine($"-------------------参数上的特性-------------------");
            // 获取指定名称的公共属性
            PropertyInfo property = type.GetProperty("Id");
            if (property.IsDefined(typeof(CustomAttribute), true))
            {
                CustomAttribute attribute = (CustomAttribute)property.GetCustomAttribute(typeof(CustomAttribute), true);
                Console.WriteLine($"{attribute.Description}_{attribute.Remark}");
                attribute.Show();
            }
        }
        #endregion

        #region 方法上的特性
        {
            Console.WriteLine($"-------------------方法上的特性-------------------");
            // 获取指定名称的方法
            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();
            }



            Console.WriteLine($"-------------------方法上传递的参数的特性-------------------");
            // 获取指定方法或者构造函数的参数
            ParameterInfo parameterInfo = method.GetParameters()[0];
            if (parameterInfo.IsDefined(typeof(CustomAttribute), true))
            {
                CustomAttribute attribute = (CustomAttribute)method.GetCustomAttribute(typeof(CustomAttribute), true);
                Console.WriteLine($"{attribute.Description}_{attribute.Remark}");
                attribute.Show();
            }


            Console.WriteLine($"-------------------方法上返回值的特性-------------------");
            // 获取指定方法的返回值
            ParameterInfo returnParameterInfo = method.ReturnParameter;
            if (returnParameterInfo.IsDefined(typeof(CustomAttribute), true))
            {
                CustomAttribute attribute = (CustomAttribute)returnParameterInfo.GetCustomAttribute(typeof(CustomAttribute), true);
                Console.WriteLine($"{attribute.Description}_{attribute.Remark}");
                attribute.Show();
            }
        }
        #endregion
    }

3.使用特性去获取美剧的备注信息

	/// <summary>
    /// 用户状态
    /// </summary>
    public enum UserState
    {
        /// <summary>
        /// 正常
        /// </summary>
        [Remark("正常")]
        Normal = 0,//左边是字段名称  右边是数据库值   哪里放描述?  注释
        /// <summary>
        /// 冻结
        /// </summary>
        [Remark("冻结")]
        Frozen = 1,
        /// <summary>
        /// 删除
        /// </summary>
        //[Remark("删除")]
        Deleted = 2
    }
    
    //枚举项加一个描述   实体类的属性也可以Display  
    //别名   映射  
    public class RemarkAttribute : Attribute
    {
        public RemarkAttribute(string remark)
        {
            this._Remark = remark;
        }
        private string _Remark = null;
        public string GetRemark()
        {
            return this._Remark;
        }
    }
    
    public static class RemarkExtension
    {
        public static string GetRemark(this Enum value)
        {
            Type type = value.GetType();
            FieldInfo field = type.GetField(value.ToString());
            if (field.IsDefined(typeof(RemarkAttribute), true))
            {
                RemarkAttribute attribute = (RemarkAttribute)field.GetCustomAttribute(typeof(RemarkAttribute), true);
                return attribute.GetRemark();
            }
            else
            {
                return value.ToString();
            }
        }
    }

4.使用特性做表单数据提交的验证:

	public static class ValidateExtension
    {
        public static bool Validate(this object oObject)
        {
            Type type = oObject.GetType();
            foreach (var prop in type.GetProperties())
            {
                if (prop.IsDefined(typeof(AbstractValidateAttribute), true))
                {
                    object[] attributeArray = prop.GetCustomAttributes(typeof(AbstractValidateAttribute), true);
                    foreach (AbstractValidateAttribute attribute in attributeArray)
                    {
                        if (!attribute.Validate(prop.GetValue(oObject)))
                        {
                            return false;//表示终止
                        }
                    }
                }

                //if (prop.IsDefined(typeof(LongAttribute), true))
                //{
                //    LongAttribute attribute = (LongAttribute)prop.GetCustomAttribute(typeof(LongAttribute), true);
                //    if (!attribute.Validate(prop.GetValue(oObject)))
                //    {
                //        return false;
                //    }
                //}
                //if (prop.IsDefined(typeof(LengAttribute), true))
                //{
                //    LengAttribute attribute = (LengAttribute)prop.GetCustomAttribute(typeof(LengAttribute), true);
                //    if (!attribute.Validate(prop.GetValue(oObject)))
                //    {
                //        return false;
                //    }
                //}
            }
            return true;
        }
    }

    public abstract class AbstractValidateAttribute : Attribute
    {
        public abstract bool Validate(object value);
    }

    [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
    public class LengAttribute : AbstractValidateAttribute
    {
        private int _Min = 0;
        private int _Max = 0;
        public LengAttribute(int min, int max)
        {
            this._Min = min;
            this._Max = max;
        }

        public override bool Validate(object value)//" "
        {
            if (value != null && !string.IsNullOrWhiteSpace(value.ToString()))
            {
                int length = value.ToString().Length;
                if (length > this._Min && length < this._Max)
                {
                    return true;
                }
            }
            return false;
        }
    }
    
    public class LongAttribute : AbstractValidateAttribute
    {
        private long _Min = 0;
        private long _Max = 0;
        public LongAttribute(long min, long max)
        {
            this._Min = min;
            this._Max = max;
        }

        public override bool Validate(object value)//" "
        {
            //可以改成一句话
            if (value != null && !string.IsNullOrWhiteSpace(value.ToString()))
            {
                if (long.TryParse(value.ToString(), out long lResult))
                {
                    if (lResult > this._Min && lResult < this._Max)
                    {
                        return true;
                    }
                }
            }
            return false;
        }
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Attribute特性是一种用于给程序元素添加额外信息的机制。在C#中,Attribute特性通常以Attribute后缀命名,并且可以附加到类、方法、属性等各种程序元素上。当Attribute特性被应用到程序元素上时,它们可以被用来提供元数据,以帮助编译器、运行时或其他代码分析工具进行处理。 引用中提到了一个约定:自定义的特性名称应该以Attribute后缀结尾。这是因为在将Attribute特性应用到程序元素上时,编译器首先会查找使用的Attribute的定义,如果找不到,则会尝试查找以"Attribute"结尾的同名特性的定义。 在引用中,提到了Attribute特性在ASP.NET开发中的应用。这表明Attribute特性在ASP.NET开发中是非常常见的,并且被广泛使用。 举个例子,引用给出了一个自定义的Attribute特性的示例代码。在这个示例中,定义了一个名为CustomAttribute特性类,它具有一个属性Desc,并提供了两个构造函数。这个示例展示了如何创建自定义的Attribute特性,并将其应用到一个名为Student的类上。 总之,Attribute特性C#中用于给程序元素添加元数据,以提供额外的信息和行为。它们是一种强大的工具,可以用于实现各种功能和扩展。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [C# 特性Attribute)](https://blog.csdn.net/qq_42335551/article/details/130268405)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [Attribute/特性心得随笔](https://download.csdn.net/download/weixin_38607552/13055291)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值