C#高级话题:特性 attribute

勇哥注:

C#的特性(attribute)常见于一些框架(例如wcf),控件(例如PropertyGrid),编译器控制等。

特性非常常见,它的本质是为对象提供额外的信息和行为,使用者可以通过反射读到这些信息或者使用这些行为。

特性是C#语言现代编程风格的重要特点。


特性常见的有两个方面的应用:

(一)可以修饰枚举。

这种应用相当于为对象添加了额外的信息。

例如下面的枚举,通过反射可以读出枚举项的额外信息。

    [Remark("用户状态")]
    public enum UserState
    {
        /// <summary>
        /// 正常
        /// </summary>
        [Remark("正常")]
        Normal = 0,
        /// <summary>
        /// 冻结
        /// </summary>
        [Remark("冻结")]
        Frozen = 1,
        /// <summary>
        /// 删除
        /// </summary>
        [Remark("删除")]
        Deleted = 2
    }


上面的特性,实际上是我们自定义的一个类,它必须继承自Attribute类。

如下图代码中,我们定义的自定义特性叫RemarkAttribute。

而在前面枚举的时候,你只需要使用名字Remark就可以了,当然你要愿意的话,也可以使用RemarkAttribute。

下面代码中使用的了扩展方法,因此你可以对使用枚举使用方法GetRemark取得这个枚举项目的特性内容。

 /// <summary>
    /// 是给枚举用  提供一个额外信息
    /// </summary>
    [AttributeUsage(AttributeTargets.Enum | AttributeTargets.Field)]
    public class RemarkAttribute : Attribute
    {
        public RemarkAttribute(string remark)
        {
            this.Remark = remark;
        }

        public string Remark { get; private set; }
    }

    public static class RemarkExtend
    {
        /// <summary>
        /// 扩展方法
        /// </summary>
        /// <param name="enumValue"></param>
        /// <returns></returns>
        public static string GetRemark(this Enum enumValue)
        {
            Type type = enumValue.GetType();
            FieldInfo field = type.GetField(enumValue.ToString());
            if (field.IsDefined(typeof(RemarkAttribute), true))
            {
                RemarkAttribute remarkAttribute = (RemarkAttribute)field.GetCustomAttribute(typeof(RemarkAttribute));
                return remarkAttribute.Remark;
            }
            else
            {
                return enumValue.ToString();
            }
        }
    }


(二)可以为属性或者字段提供范围检查

这种相当于为对象添加了额外的行为操作。

例如下面是为字段添加的带有检查数据范围行为的特性:

    [Custom(123, Description = "1234", Remark = "2345")]//方法不行
    public class Student
    {
        [CustomAttribute]
        public int Id { get; set; }
        [Leng(5,10)]//还有各种检查
        public string Name { get; set; }
        [Leng(20, 50)]
        public string Accont { get; set; }

        /// <summary>
        /// 10001~999999999999
        /// </summary>
        [Long(10001, 999999999999)]
        public long QQ { get; set; }
    }

上面的特性Leng,来源于下面的自定义特性类

  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;
        }
    }


(三)特性的总结

1。特性attribute,和注释的区别是:注释你无法通过反射取得,但是特性可以。

   一个特性,如果没有使用者,它将无任何作用。

   特性的使用者,可以是一个类,或者是一个框架,或者是编译器,或者是VistualStudio。

   例如下面的特性:

     [Obsolete("请不要使用这个了,请使用什么来代替", true)]   //这个影响编译器的运行

     [Serializable]    //可以序列化和反序列化  可以影响程序的运行

     其它的常见的特性有: wcf, MVC filter等。


2。 声明和使用attribute,AttributeUsage

     特性可以修饰类、类的方法、类的属性、类的字段、枚举或枚举项。

     被特性修饰后的对象,在C#的中间语言IL中,会插入一些类,以存储额外的信息或者行为。

     只有通过ILSpy这类反编译工具才能看到这些变化。而在C#代码层面上,表面上特性就跟加一个注释没有什么区别。


3。特性的意义是运行中获取attribute:额外信息、 额外操作


--------------------- 

作者:hackpig

来源:www.skcircle.com

版权声明:本文为博主原创文章,转载请附上博文链接!


本文出自勇哥的网站《少有人走的路》wwww.skcircle.com,转载请注明出处!讨论可扫码加群:
本帖最后由 勇哥,很想停止 于 2024-05-06 21:33:18 编辑

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

会员中心
搜索
«    2025年4月    »
123456
78910111213
14151617181920
21222324252627
282930
网站分类
标签列表
最新留言
    热门文章 | 热评文章 | 随机文章
文章归档
友情链接
  • 订阅本站的 RSS 2.0 新闻聚合
  • 扫描加本站机器视觉QQ群,验证答案为:halcon勇哥的机器视觉
  • 点击查阅微信群二维码
  • 扫描加勇哥的非标自动化群,验证答案:C#/C++/VB勇哥的非标自动化群
  • 扫描加站长微信:站长微信:abc496103864
  • 扫描加站长QQ:
  • 扫描赞赏本站:
  • 留言板:

Powered By Z-BlogPHP 1.7.2

Copyright Your skcircle.com Rights Reserved.

鄂ICP备18008319号


站长QQ:496103864 微信:abc496103864