C# 特性

本文介绍了C#中的特性,包括特性的作用、如何使用特性为程序集添加元数据信息,以及如何创建自定义特性。通过示例展示了如何定义一个名为'Required'的特性,用于标记字段为必填,并利用反射进行验证。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

特性

先看一个例子:
在VS中添加一个类库项目和一个控制台项目,在控制台项目中编写以下代码。(控制台项目添加类库项目的程序集)

        static void Main(string[] args)
        {
            Assembly assembly = Assembly.GetAssembly(typeof(Class1));
            Console.WriteLine("程序集名称:"+assembly.FullName);
            assembly.GetCustomAttributes();
            Console.WriteLine("程序集Title:" + 
assembly.GetCustomAttribute<AssemblyTitleAttribute>().Title);
            Console.WriteLine("程序集描述:" + 
assembly.GetCustomAttribute<AssemblyDescriptionAttribute>().Description);
            Console.WriteLine("程序集公司:" + 
assembly.GetCustomAttribute<AssemblyCompanyAttribute>().Company);
            Console.Read();
        }

其中Class1是类库项目的类。
执行后可以得到该类库项目输出的程序集的信息。例如:
在这里插入图片描述

在VS创建类库项目(以及其他的一些项目)时,会添加一个名为“AssemblyInfo.cs”的文件,其中内容如下:

using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("ClassLibrary1")]
[assembly: AssemblyDescription("测试程序集")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("程序开发公司")]
[assembly: AssemblyProduct("ClassLibrary1")]
[assembly: AssemblyCopyright("Copyright ©  2019")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 会使此程序集中的类型
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("e15c7334-bcfc-4c09-a0bc-3798f7742fc8")]
// 程序集的版本信息由下列四个值组成: 
//
//      主版本
//      次版本
//      生成号
//      修订号
//
// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

这个文件并不是某个类文件,而是为程序集添加额外说明信息的文件,其中运用了很多特性——即使用"[]"包括起来的内容。

特性

特性可以可以为程序添加更多的元数据信息。上面的例子中,使用程序集特性为程序集class1添加了标题,程序集描述,创建公司,版权声明等等信息。除此之外,特性还可以用于如:

  • 委托
  • 枚举
  • 事件
  • 字段
  • 泛型参数
  • 接口
  • 方法
  • 属性
    ····
    (可以参考AttributeTargets提供的选项)

特性可以作为一种特殊的类来对待,只是特性类统一继承于System.Attribute,使用特性时,通常可以不带Attribute后缀。

一个自定义特性的例子

一个普通的类继承System.Attribute之后,就成为了一个特性类。在命名类名通常会加上Attribute,例如:

      [System.AttributeUsage(AttributeTargets.Property, Inherited = false, 
AllowMultiple = true)]
      sealed class RequiredAttribute : Attribute
    {
        private bool flag;
        public RequiredAttribute(bool flag)
        {
            this.flag = flag;
        }
        public bool Flag
        {
            get { return flag; }
        }
    }

上面的特性Required标记了某个属性是必须的,并且通过AttributeTargets确定了只能用于属性字段。
可以看到:
特性类是密封类;
特性类也有构造器;
其中System.AttributeUsage可以用来限定自定义特性,(相当于特性的特性)

使用特性修饰

如下代码,定义了一个类,并限定某些字段为必须的

    public class FormClass
    {
        [Required(true)]
        public string ID { get; set; }
        [Required(true)]
        public string Name { get; set; }
        public string Birthday { get; set; }
    }

在网页提交表单是通常要做一些验证,常常就有检验字段是否为空的(当然,表单验证通常不会放在后台来做)。对于FormClass,验证其是否符合要求,可以用反射的方法获取所有的属性,获取属性上的特性标记,判断是否符合特性的要求。

  public class Validator<T>
    {
        private T data;
        public Validator(T data){
           this.data = data;
        }
        //是否已经验证
        bool isValidate { get; set; }
        //验证方法
        bool Validate()
        {
            PropertyInfo[] properties = data.GetType().GetProperties();
            foreach (var item in properties)
            {
                RequiredAttribute required = 
item.GetCustomAttribute<RequiredAttribute>();
                if (required!= null&&required.Flag == true && item.GetValue(data) == 
null)
                {
                    return false;
                }
                else
                {
                    continue;
                }
            }
            return true;
        }
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值