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

.Net 框架提供了两种类型的特性:预定义特性和自定义特性。

一、运用范围

程序集,模块,类型(类,结构,枚举,接口,委托),字段,方法(含构造),方法,参数,方法返回值,属性(property),Attribute

  [AttributeUsage(AttributeTargets.All)]
public class TestAttribute : Attribute
{
}
[TestAttribute]//结构
public struct TestStruct { } [TestAttribute]//枚举
public enum TestEnum { } [TestAttribute]//类上
public class TestClass
{
[TestAttribute]
public TestClass() { } [TestAttribute]//字段
private string _testField; [TestAttribute]//属性
public string TestProperty { get; set; } [TestAttribute]//方法上
[return: TestAttribute]//定义返回值的写法
public string TestMethod([TestAttribute] string testParam)//参数上
{
throw new NotImplementedException();
}
}

这里我们给出了除了程序集和模块以外的常用的Atrribute的定义。

二、自定义Attribute

为了符合“公共语言规范(CLS)”的要求,所有的自定义的Attribute都必须继承System.Attribute。

第一步:自定义一个检查字符串长度的Attribute

[AttributeUsage(AttributeTargets.Property)]
public class StringLengthAttribute : Attribute
{
private int _maximumLength;
public StringLengthAttribute(int maximumLength)
{
_maximumLength = maximumLength;
} public int MaximumLength
{
get { return _maximumLength; }
}
}

AttributeUsage这个系统提供的一个Attribute,作用来限定自定义的Attribute作用域,这里我们只允许这个Attribute运用在Property上,内建一个带参的构造器,让外部传入要求的最大长度。

第二步:创建一个实体类来运行我们自定义的属性

public class People
{
[StringLength(8)]
public string Name { get; set; } [StringLength(15)]
public string Description { get; set; }
}

定义了两个字符串字段Name和Description, Name要求最大长度为8个,Description要求最大长度为15.

第三步:创建验证的类

public class ValidationModel
{ public void Validate(object obj)
{
var t = obj.GetType(); //由于我们只在Property设置了Attibute,所以先获取Property
var properties = t.GetProperties();
foreach (var property in properties)
{ //这里只做一个stringlength的验证,这里如果要做很多验证,需要好好设计一下,千万不要用if elseif去链接
//会非常难于维护,类似这样的开源项目很多,有兴趣可以去看源码。
if (!property.IsDefined(typeof(StringLengthAttribute), false)) continue; var attributes = property.GetCustomAttributes();
foreach (var attribute in attributes)
{
//这里的MaximumLength 最好用常量去做
var maxinumLength = (int)attribute.GetType().
GetProperty("MaximumLength").
GetValue(attribute); //获取属性的值
var propertyValue = property.GetValue(obj) as string;
if (propertyValue == null)
throw new Exception("exception info");//这里可以自定义,也可以用具体系统异常类 if (propertyValue.Length > maxinumLength)
throw new Exception(string.Format("属性{0}的值{1}的长度超过了{2}", property.Name, propertyValue, maxinumLength));
}
} }
}

这里用到了反射,因为Attribute一般都会和反射一起使用,这里验证了字符串长度是否超过所要求的,如果超过了则会抛出异常

private static void Main(string[] args)
{
var people = new People()
{
Name = "qweasdzxcasdqweasdzxc",
Description = "description"
};
try
{
new ValidationModel().Validate(people);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadLine();
}

c#核心基础 - 浅谈 c# 中的特性 Attribute)的更多相关文章

  1. C#核心基础--浅谈类和对象的概念

    浅谈类和对象的概念 一.什么是类?什么是对象? 学习一门面向对象编程语言,我们必须得知道什么是类?什么是对象? 类(Class)实际上是对某种类型的对象定义变量和方法的原型.它表示对现实生活中一类具有 ...

  2. 视频基础知识:浅谈视频会议中H.264编码标准的技术发展

    浅谈视频会议中H.264编码标准的技术发展 浅谈视频会议中H.264编码标准的技术发展 数字视频技术广泛应用于通信.计算机.广播电视等领域,带来了会议电视.可视电话及数字电视.媒体存储等一系列应用,促 ...

  3. Java基础学习总结(29)——浅谈Java中的Set、List、Map的区别

    就学习经验,浅谈Java中的Set,List,Map的区别,对JAVA的集合的理解是想对于数组: 数组是大小固定的,并且同一个数组只能存放类型一样的数据(基本类型/引用类型),JAVA集合可以存储和操 ...

  4. 浅谈C中的malloc和free

    转自http://bbs.bccn.net/thread-82212-1-1.html非常感谢作者 浅谈C中的malloc和free 在C语言的学习中,对内存管理这部分的知识掌握尤其重要!之前对C中的 ...

  5. 浅谈JS中的闭包

    浅谈JS中的闭包 在介绍闭包之前,我先介绍点JS的基础知识,下面的基础知识会充分的帮助你理解闭包.那么接下来先看下变量的作用域. 变量的作用域 变量共有两种,一种为全局变量,一种为局部变量.那么全局变 ...

  6. 【分析】浅谈C#中Control的Invoke与BeginInvoke在主副线程中的执行顺序和区别(SamWang)

    [分析]浅谈C#中Control的Invoke与BeginInvoke在主副线程中的执行顺序和区别(SamWang) 今天无意中看到有关Invoke和BeginInvoke的一些资料,不太清楚它们之间 ...

  7. 浅谈JS中的!=、== 、!==、===的用法和区别 JS中Null与Undefined的区别 读取XML文件 获取路径的方式 C#中Cookie,Session,Application的用法与区别? c#反射 抽象工厂

    浅谈JS中的!=.== .!==.===的用法和区别   var num = 1;     var str = '1';     var test = 1;     test == num  //tr ...

  8. [转]浅谈电路设计中应用DDR3处理缓存问题

    本文转自:浅谈电路设计中应用DDR3处理缓存问题_若海人生的专栏-CSDN博客 DDR系列SDRAM存储芯片的高速率.高集成度和低成本使其理所当然成为存储芯片中的一霸.在PC和消费电子领域自是如此,它 ...

  9. 浅谈Java中的equals和==(转)

    浅谈Java中的equals和== 在初学Java时,可能会经常碰到下面的代码: 1 String str1 = new String("hello"); 2 String str ...

随机推荐

  1. Docker -v 对挂载的目录没有权限 Permission denied

    1.问题 今天在使用docker挂载redis的时候老是报错 docker run -v /home/redis/redis.conf:/usr/local/etc/redis/redis.conf ...

  2. 5.JAVA-内部类实例

    在JAVA中,类内部可以添加其它类,当然也可以实现类继承(后续章节学习). 本章示例-实现部门类和雇员类 可以通过部门对象,查找该部门的雇员信息. 可以通过雇员对象,查找该雇员所在的部门信息 代码如下 ...

  3. Jenkins忘记admin密码处理方法

    1.先找到enkins/config.xml文件,并备份. 此文件位于Jenkins系统设置的主目录,根据自己的配置情况而定.我的位置如下 /data/temp/jenkins/config.xml2 ...

  4. 联发科Helio P90(mt6779),P70(mt6775),P60(MT6771),P35,P22(MT6762)芯片参数规格

    Helio P90(mt6779)是一款人工智能处理平台,集成了超级强大的AI专核APU 2.0,具有超强的AI性能和一系列基于人工智能的成像升级.该芯片将重新定义消费者对智能手机AI功能的体验.He ...

  5. 一起学Android之Menu

    概述 菜单(Menu)在Android开发中,是一种常见的用户界面组件,通过使用菜单Api可以给用户提供常见的一致的体验.本文主要讲解三种菜单的相关内容. 菜单的分类 选项菜单(OptionsMenu ...

  6. ORACLE字符集修改ORA-02374\ORA-12899\ORA-02372

    IMPDP时部分日志显示这个警告ORA-02374: conversion error loading table "MEMXXX"."T_MEMBER_XXXX&quo ...

  7. App瘦身、性能优化总结

    App瘦身 资源瘦身 使用tinypng压缩PNG图片.视频可以通过 Final cut等软件进行分辨率压缩.音频则降低码率即可. 非必须资源文件可以放到自己服务器上 启动图使用 LaunchScre ...

  8. 你可能需要为你的 APP 适配 iOS 11

    本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:https://mp.weixin.qq.com/s/AZFrqL9dnlgA6Vt2sVhxIw 作者:s ...

  9. Python用Django写restful api接口

    用Python如何写一个接口呢,首先得要有数据,可以用我们在网站上爬的数据,在上一篇文章中写了如何用Python爬虫,有兴趣的可以看看: https://www.cnblogs.com/sixrain ...

  10. Servlet不再是烦恼

    Servlet 一.什么是Servlet? Servlet是在服务器上运行的小程序,也就是一个Java类,但比较特殊,不需要new,自动就可以运行.也有创建.垃圾回收和销毁过程.Servlet是Jav ...