C# 特性(Attribute)

一、什么是特性?

  1. 特性本质是一个class(类),声明的时候默认以Attribute结尾,直接或者间接继承Attribute抽象类

  2. 应用特性,是把这个特性以[ ]包裹标记在类或者类的成员上

  3. Attribute是一种可由用户自有定义的修饰符(Modifier),可以用来修饰各种需要被修饰的目标。我们可以对类、以及C#程序集中的成员进行进一步的描述

代码示列:

			[Serializable]
			public class SampleClass
			{
   				 // Objects of this type can be serialized.
			}

二、特性与注释的区别

  1. 注释只是一段描述文字,这段描述是给人看的,在编译器编译之后是不存在

  2. Attribute是程序代码的一部分,它不但不会被编译器丢弃,而且还会被编译器编译进程序集
    Assembly)的元数据(Metadata)里。在程序运行的时候,随时可以从元数据(元数据:.NET中元数据是指程序集中的命名空间、类、方法、属性等信息,这些信息是可以通过Reflection读取出来的。)中提取提取出这些附加信息,并以之决策程序的运行。

三、如何自定义特性

  1. 标记的特性,如果是以Attribute结果,Attribute可以省略掉

  2. 可以标记的类内部的任何成员上

  3. 特性在标记的时候,其实就是去调用构造函数

  4. 在标记的时候也可以对公开的属性或者字段赋值

  5. 特性标记默认是不能重复标记的

  6. AttributeUsage:也是一个特性,是用来修饰特性的特性–约束特性的特性

  7. AttributeTargets指定当前特性只能标记在某个地方;建议大家在自己定义特性的时候,最好能够明确指定AttributeTargets–明确告诉别人,我这个特性是专们用来标记在哪里的.

  8. AllowMultiple:是否可以重复标记.

  9. Inherited:是否可以继承特性.

代码示列:

//完整写法
[CustomAttribute("Jun")]
[CustomAttribute("Sun")]
public static void Test()
{
	Console.WriteLine("Hello Jun Sun"); 
}
//省去Attribute写法
[Custom("Jun")]
[Custom("Sun")]
public static void Test2()
{
	Console.WriteLine("Hello Jun Sun"); 
}
//执行的顺序
[Custom("Sub")]
[Custom("Jun")]
public static void Test3()
{
	Console.WriteLine("Sun Jun"); 
}
//单括号叠加
[Custom("Sun"),Custom("Jun")]
public static void Func()
{
	Console.WriteLine("Sun Jun"); 
}

四、如何调用特性内部的成员

  1. 进过反编译之后,在标记有特性的类的内部,生成了cutom的成员,但是我们不能直接调用.

  2. 在使用反射获取特性的时候,可以把标记在任何地方的特性都可以获取到

  3. 既然标记的特性可以通过反射来获取到实例,就可以加以应用

代码实例:

public class InvokeAttributeManager
    {
        /// <summary>
        /// 通过反射来调用特性---确实是可以调用到特性的实例的
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        public static void Show(Student student)
        {
            //Type type = typeof(Student);
            Type type = student.GetType(); 
            //1.先判断是否有特性
            if (type.IsDefined(typeof(CustomAttribute), true))
            { 
                //2.获取--先判断再获取--为了提高性能
                foreach (CustomAttribute attribute in type.GetCustomAttributes(true))
                {
                    Console.WriteLine($"attribute._Name:{attribute._Name}");
                    Console.WriteLine($"attribute._Age:{attribute._Age}"); 
                    attribute.Do();
                }
            }

            //获取当前Type下所有的属性上标记的特性
            foreach (PropertyInfo prop in type.GetProperties())
            {
                if (prop.IsDefined(typeof(CustomAttribute), true))
                {
                    //2.获取--先判断再获取--为了提高性能
                    foreach (CustomAttribute attribute in prop.GetCustomAttributes(true))
                    {
                        Console.WriteLine($"attribute._Name:{attribute._Name}");
                        Console.WriteLine($"attribute._Age:{attribute._Age}");
                        attribute.Do();
                    }
                }
            }

            //获取当前Type下所有的字段上标记的特性
            foreach (FieldInfo field in type.GetFields())
            {
                if (field.IsDefined(typeof(CustomAttribute), true))
                {
                    //2.获取--先判断再获取--为了提高性能
                    foreach (CustomAttribute attribute in field.GetCustomAttributes(true))
                    {
                        Console.WriteLine($"attribute._Name:{attribute._Name}");
                        Console.WriteLine($"attribute._Age:{attribute._Age}");
                        attribute.Do();
                    }
                }
            }

            //获取当前Type下所有的方法上标记的特性
            foreach (MethodInfo method in type.GetMethods())
            {
                foreach (ParameterInfo para in method.GetParameters())
                {
                    if (para.IsDefined(typeof(CustomAttribute), true))
                    {
                        //2.获取--先判断再获取--为了提高性能
                        foreach (CustomAttribute attribute in para.GetCustomAttributes(true))
                        {
                            Console.WriteLine($"attribute._Name:{attribute._Name}");
                            Console.WriteLine($"attribute._Age:{attribute._Age}");
                            attribute.Do();
                        }
                    }
                }

                if (method.IsDefined(typeof(CustomAttribute), true))
                {
                    //2.获取--先判断再获取--为了提高性能
                    foreach (CustomAttribute attribute in method.GetCustomAttributes(true))
                    {
                        Console.WriteLine($"attribute._Name:{attribute._Name}");
                        Console.WriteLine($"attribute._Age:{attribute._Age}");
                        attribute.Do();
                    }
                }
            }
        }
    }
staic void Main(int[] args)
   {
                People people = new People()
                {
                    Id = 1,
                    Name = "明天我是否在"
                };
                people.custom//调用不到 
                InvokeAttributeManager.Show(people);
  }

五、特性获取额外信息

  1. 特性获取描述信息—获取额外信息
  2. 通过反射、特性、扩展方法,可以封装一个获取额外新的的公共方法

代码示列:

 [AttributeUsage(AttributeTargets.Field)]
    public class RemarkAttribute : Attribute
    {
        private string _Description;

        public RemarkAttribute(string decription)
        {
            this._Description = decription;
        }
         
        public string GetRemark()
        {
            return this._Description;
        }
    }
    public enum UserStateEnum 
    {
        [Remark("正常状态")]
        Normal = 1,
        [Remark("已冻结")]
        Frozen = 2,
        [Remark("已删除")]
        Deleted = 3,
        [Remark("其他")]
        Other = 4
    }
 public static class RemarkAttributeExtension
    {
        /// <summary>
        /// 扩展方法
        /// </summary>
        /// <param name="enum"></param>
        /// <returns></returns>
        public static string GetRemark(this Enum @enum)
        {
            Type type = @enum.GetType();
            string fieldName = @enum.ToString();
            FieldInfo field = type.GetField(fieldName);
            if (field.IsDefined(typeof(RemarkAttribute), true))
            {
                //RemarkAttribute attribute = (RemarkAttribute)field.GetCustomAttribute(typeof(UserStateEnum), true); 
                RemarkAttribute attribute = field.GetCustomAttribute<RemarkAttribute>();
                string description = attribute.GetRemark();
                return description;
            }
            return @enum.ToString();
        }
    }
static void Main(string[] args)
{
             UserStateEnum normal = UserStateEnum.Normal;
             UserStateEnum frozen = UserStateEnum.Frozen;
             UserStateEnum deleted = UserStateEnum.Deleted;
             UserStateEnum other = UserStateEnum.Other;
             UserStateEnum other1 = UserStateEnum.Other1;
             string strnormalRemark = RemarkAttributeExtension.GetRemark(normal);
             string strfrozenRemark = RemarkAttributeExtension.GetRemark(frozen);
             string strdeletedRemark = RemarkAttributeExtension.GetRemark(deleted);
             string strotherRemark = RemarkAttributeExtension.GetRemark(other);
             string strother1Remark = RemarkAttributeExtension.GetRemark(other1);				
}

本人学习分享,如有错误,欢迎指正,请勿谩骂(* ̄︶ ̄)

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 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、付费专栏及课程。

余额充值