C#深入学习--特性

目录

一、概述

二、基本概念

三、自定义特性

四、给对象的属性自定义验证规则

五、总结


 

一、概述

特性,说的白话一点,就是说明某个东西的特殊性,它不能单独存在,必须依附在某个东西上,这里的东西是指C#代码中类,属性,方法。特性就是对这些类,方法,属性进一步修饰。比如说,定义个 sting 类型 属性A ,我们要求该属性最小长度为5.这个要求就可以说是它的特性。

二、基本概念

特性:一个继承于Attribute的特殊类,以“[attribut()]”的方式依附在属性,方法,类等其它 Type类型上,从而对其进行约束,如下:

        [Required]
        public string EmpNo { get; set; }

其中[Required] 就是对EmpNo属性修饰,约束EmpNo不能为null,否则参数校验就会出错。

三、自定义特性

3.1 定义特性无参构造函数&使用

    //[AttributeUsage(AttributeTargets.All)]                                //表示对该特性运用地方没有限制
    //[AttributeUsage(AttributeTargets.Property|AttributeTargets.Field)]    //表示该特性只能运用到Property和Field 
    //[AttributeUsage(AttributeTargets.All,AllowMultiple = true)]           //AllowMultiple =  true 表示该特性在同一对象上多次引用
    [AttributeUsage(AttributeTargets.Property)]                             //表示该特性只能运用到Property
    public class MaxLengthValidateAttribute: Attribute
    {
    }

    public class User
    {
        [MaxLengthValidate()]                                             //应用自定义Attribute
        public string EmpNo { get; set; }
    }

3.2 自定义带参构造函数特性&使用&给内部属性【ErrMsg】赋值

    [AttributeUsage(AttributeTargets.Property)]                        
    public class MaxLengthValidateAttribute: Attribute
    {

        private int _Max { get; set; };
        public string ErrMsg { get; set; };
        public MaxLengthValidateAttribute(int max)
        {
            _Max = max;
        }
    }
    public class User
    {
        [MaxLengthValidate(max:5,ErrMsg ="EmpNo 最大长度为5")]    //调用有参构造函数,并给属性ErrMsg赋值
        public string EmpNo { get; set; }

    }

注意事项:需要多个属性值赋值,用“,”号隔开

四、给对象的属性自定义验证规则

场景设置:现在我们需要设置某些string类型的长度,Int类型的大小范围。若我们创建的类的实例如果属性不满足要求就报错

1. 创建一个验证抽象 Atrribute=>【MyValidateAtrribute】(抽象出来的好处将在后面解析)

    /// <summary>
    /// 定义一个抽象Atrribute
    /// </summary>
    [AttributeUsage(AttributeTargets.Property)]  
    public abstract class MyValidateAtrribute:Attribute
    {
        /// <summary>
        /// 记录验证失败信息
        /// </summary>
        public abstract string ErrMsg { get; set; }

        /// <summary>
        /// 定义验证规则
        /// </summary>
        /// <param name="oValue"></param>
        /// <returns></returns>
        public abstract bool Validate(object oValue);
    }

2. 创建两个继承MyValidateAtrribute 的Atrribute,分别为

StringLengthAtrribute => 验证String属性最大长度和最小长度

IntRangAttribute          => 验证Int类型大小

    /// <summary>
    /// 验证String属性最大长度和最小长度
    /// </summary>
    public class StringLengthAtrribute : MyValidateAtrribute
    {
        /// <summary>
        /// 最大长度
        /// </summary>
        public long Max { get; set; } = 9999;

        /// <summary>
        /// 最长度
        /// </summary>
        public long Min { get; set; } = 0;

        public override string ErrMsg { get; set; }

        public override bool Validate(object oValue)
        {
            return oValue.ToString().Length >= Min && oValue.ToString().Length <= Max;
        }
    }
    /// <summary>
    /// 验证Int类型大小
    /// </summary>
    public class IntRangAttribute : MyValidateAtrribute
    {
        /// <summary>
        /// long最大值
        /// </summary>
        public long Max { get; set; }

        /// <summary>
        /// long最小值
        /// </summary>
        public long Min { get; set; }

        public override string ErrMsg { get; set; }
  
        public override bool Validate(object oValue)
        {
            if (long.TryParse(oValue.ToString(), out long longValue))
            {
                if (longValue >= Min && longValue <= Max)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            } else
            {
                ErrMsg = "该参数不支持IntRang属性验证!";
                 return false;
            }
        }
    }

3. 创建一个记录验证失败结果的类

    /// <summary>
    /// 记录验证失败结果类
    /// </summary>
    public class ValidateErrResult 
    {
        /// <summary>
        /// 属性名称
        /// </summary>
        public string PropName { get; set; }
        /// <summary>
        /// 错误信息
        /// </summary>
        public string ErrMsg { get; set; }

    }

4. 通过泛型创建一个class的属性验证方法

    /// <summary>
    /// 针对类属性验证
    /// </summary>
    public class MyPropValidate
    {
        /// <summary>
        /// 对class 属性进行验证合法性
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static List<ValidateErrResult> Validate<T>(T obj) 
            where T:class
        {
            var reValidateErr = new List<ValidateErrResult>();    //定一个验证失败结果集
            var type = typeof(T);
            var props = type.GetProperties()
                .Where(prop => prop.IsDefined(typeof(MyValidateAtrribute), true));  //获取包含 MyValidateAtrribute 的特性
            foreach (var prop in props)
            {
                var value = prop.GetValue(obj);                   //获取该属性的值   
                foreach (MyValidateAtrribute attribute in prop.GetCustomAttributes(typeof(MyValidateAtrribute), true))  //获取该属性所有 MyValidateAtrribute 的特性
                {
                    if (!attribute.Validate(value))   //验证失败
                    {
                        reValidateErr.Add(new ValidateErrResult() { PropName = prop.Name, ErrMsg = attribute.ErrMsg });
                    }
                }

            }
            return reValidateErr;
        }
    }

注意事项:

该处直接去找有【MyValidateAtrribute】特性的属性,避免了单独分别处理【StringLengthAtrribute】 和【IntRangAttribute】,应为他们都继承于【MyValidateAtrribute】而且都实现了【Validate】方法

5.创建测试类 EmpInfo

    public class EmpInfo
    {
        public int Id { get; set; }

        [StringLengthAtrribute(Min = 8, Max = 10, ErrMsg = "工号格式有误")]
        public string EmpNo { get; set; }

        [IntRang(Min = 18, Max = 45, ErrMsg = "年龄不符合要求!")]
        public int Age { get; set; }
    }

6.测试

                Console.WriteLine("*********************特性研究*****************");
                var user = new EmpInfo()
                {
                    Id = 0,
                    EmpNo = "A005485sg",
                    Age = 50
                };
                foreach (var item in MyPropValidate.Validate<EmpInfo>(user))
                {
                    Console.WriteLine($"异常参数名称:{item.PropName};错误信息:{item.ErrMsg}");

                }
                var user2 = new EmpInfo()
                {
                    Id = 0,
                    EmpNo = "A005485aaaaeb",
                    Age = 28
                };
                foreach (var item in MyPropValidate.Validate<EmpInfo>(user2))
                {
                    Console.WriteLine($"异常参数名称:{item.PropName};错误信息:{item.ErrMsg}");

                }

7.测试结果

五、总结

特性是对Type的额外描述,它也是一个类,其实在C#编译成中间语言IL的后,可以通过反编译软件看到有特性的地方其实会自动生成一个类的实例,但是在C# 中不能直接使用,所以在反射的时候可以获得该对象访问其中的属性和方法。本文的实例其实在系统中早也有实现,在using System.ComponentModel.DataAnnotations;中有很多属性约束,例如:[Required],[MaxLength()] 等等。这里只是想说明,属性一般怎么去用。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
学习安排:4周4个项目实战 学习形式:录播视频+在线作业考核+助教一对一辅导答疑 1. C#基本语法:基本编程(If:…else)语句、数组等。2. C#面向对象编程:封装、继承、多态性、面向接口编程、动态多态性、字符串基础等。3. .Net 框架原理讲解:多维数组、可变参数 Params、类的实例化内存分配机制等。4. 深入学习对象类型:里氏替换原则(LSP)、类的属性极其本质特性、IS ,AS 关键字、深入学习字符串理论、枚举类型以及适用场合。5. 深入学习集合特性:索引器、自定义集合、深入刨析集合类型本质(ArrayList、HashTable)、学习泛型集合、泛型约束等。6. 学习委托与事件:委托与事件的区别、匿名方法、Lambda表达式。7. 正则表达式。8. 查询表达式Linq。9. 反射、特性、动态编程。10. 多线程编程。11. Socket通讯技术。 第二模块:Unity 入门与基础 学习安排:4周3个项目实战 学习形式:录播视频+在线作业考核+助教一对一辅导答疑 课程内容:游戏与Unity发展历史概述、 3D 模型基础、 地形编辑器、光源、音频、Unity脚本程序基础、GUI、3D模型动画的导入 与基本应用、物理学模拟(初级)、碰撞盒与触发器、协程、SendMessage数据传值技术等。 学习安排:4周4个项目实战 学习形式:录播视频+在线作业考核+助教一对一辅导答疑 课程内容:讲解粒子系统、Mecanim、导航寻路、Unity游戏移植技术、Mecanim 动画系统、导航寻路、项目研发常用优化策略、Unity游戏移植与手指触控识别、射线、数据持久化、对象缓冲池技术、物理学模拟(铰链关节(Hinge Joint)、弹簧关节 、固定关节、角色关节)与资源动态加载技术(AssetBundle与WWW)等。 第四模块:Unity项目实训: ARPG项目"地下守护神" 学习安排:4周1个项目实战 学习形式:录播视频+在线作业考核+助教一对一辅导答疑 课程内容:1:前端分层的MVC架构搭建,开发自定义的资源动态加载插件、音频插件、对话系统插件、事件监听插件等。2: UI粒子特效、场景淡入淡出控制。3: 单机与移动端的双输入控制系统开发。4: 数值平衡处理与开发。5: 多种设计模式在游戏研发过程中的灵活运用。6: XML技术的灵活运用,在系统解耦与资源国际化方面的技术突破。7: 开发强大灵活的日志系统插件,应对服务器与移动端的各种复杂系统调试需求。8:开发“对话系统”,与“新手导航”。9:开发基于XML的对象持久化技术。10:开发“背包系统”、“商城系统”、“公告系统”、“任务系统”。11:开发“副本”多种类怪物的战斗系统。12:开发各种战斗特效系统: “血条”、“漂字”、“连击”等功能。 第五模块:虚拟现实(VR)与增强现实技术(AR) 学习安排:1周2个项目实战 学习形式:录播视频+在线作业考核+助教一对一辅导答疑 课程内容:R虚拟现实技术开发:先从什么是虚拟现实(VR)、虚拟现实的主要特点、虚拟现实技术的基础底层原理、国际与国内的产业布局、国际权威机构未来发展趋势预测等讲起。然后主要介绍国际主要领军品牌:Oculus、HTC、SonyVR等产品规格、主要性能指标等。最后重点以一款国内著名VR产品:3Glasses 为代表,介绍VR产品的具体使用、维护、与开发项目全过程流程等。AR 增强实现开发:讲解什么是增强现实、注册高通AR账号、制作识别图、SDK下载与制作、打包发布
### 回答1: c是一个字母,也是拉丁字母表中的第三个字母。在英语中,c的发音是/k/,它有时候也可以发/s/或/tʃ/的音。在汉语拼音中,c用来表示[t͡s]的发音。c在数学中也有一些特殊的意义,比如常数c表示光速、频率单位赫兹(Hz)中的常数。c还可以是化学元素的符号,比如碳(Carbon)的化学符号就是C。C还是计算机编程语言中的一种,它是一种通用的高级编程语言,被广泛应用于软件开发。C语言是一种结构化的、面向过程的语言,它具有高效、灵活和可移植的特点,因此在计算机领域中被广泛使用。总的来说,c是一个常用的字母,不仅在语言中有着重要的地位,还在数学、化学和计算机领域中有着独特的意义。 ### 回答2: C 是一种广泛使用的编程语言,最初是由丹尼斯·里奇在贝尔实验室开发的。它作为一种高级语言,具有简洁、可移植、高效的特点,被广泛用于系统软件、嵌入式系统和应用软件的开发。C 语言具有丰富的语法和强大的功能,可以进行底层的系统操作,如内存管理、指针操作等。 C 语言的语法简单明了,易于学习和理解。它有丰富的运算符和控制流结构,使得程序员可以方便地进行各种计算和逻辑判断。此外,C 语言还支持面向过程的编程风格,可以通过定义和调用函数来组织和管理代码。 C 语言还具有高效的性能特点。由于它是一种编译型语言,程序在执行之前会被编译为机器码,因此执行效率很高。C 语言的底层操作和指针功能也使得程序员可以更灵活地进行内存管理和资源优化。 除此之外,C 语言也有一些缺点。比如,C 语言的语法相对较为繁琐,需要程序员自己管理内存,这可能导致一些常见的编程错误,如指针错误和内存泄漏。此外,C 语言也缺乏一些高级的特性,如垃圾回收和面向对象编程等。 总之,C 语言是一种非常重要和有影响力的编程语言。它的简洁和高效性使其成为开发底层系统和性能敏感应用的理想选择。虽然它有一些缺点,但对于想要深入了解计算机底层原理和操作的程序员来说,C 语言是必不可少的工具。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值