• 了解attribute

Attribute 只是将一些附加信息与某个目标元素关联起来的方式。

Attribute 是一个类,这个类可以提供一些字段和属性,不应提供公共方法,事件等。在定义attribute类的构造方法,字段和属性时,对数据类型有严格的要求,一般要求为: Boolean, Char, Byte, Sbyte, Int16, UInt16, Int32, Int64,Single, Double, String, Type, Object, Enum, 可以使用数组,但是并不提倡使用。

  • 使用attribute

 [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, Inherited = false)]
[Conditional("Specify")]
public class DisplayNameAttribute : Attribute
{
public string PropertyName { get; set; } public DisplayNameAttribute()
{ } public DisplayNameAttribute(string propertyName)
{
this.PropertyName = propertyName;
}
}
  • 检测attribute
  1. attribute定义和应用之后还没有任何意义,只有在运行的时候去检测,然后根据对应的attribute做一些不同事情才让attribute变得有意义,那么如何检测attribute呢?

方法名称

说明

IsDefined

如果至少有一个指定的Attribute派生类的实例与目标关联,就返回true。这个方法效率很高,因为他不构造(反序列化)attribute类的任何实例

GetCustomAttributes

返回一个数组,其中每个元素都是应用于目标的指定attribute类的一个实例。

如果不为这个方法指定具体的attribute类,数组中包含的就是已应用的所有attribute的实例,不管他们是什么类。每个实例都使用编译时指定的参数、字段和属性来构造(反序列化)。如果目标没有应用任何attribute类的实例,就返回一个空数组。该方法通常用于已将AllowMultiple 设为true的attribute

GetCustomAttribute

返回应用于目标的指定attribute类的一个实例。实例使用编译是指定的参数、字段和属性来构造(反序列化)。如果目标没有应用任何attribute类的实例,就返回null。如果目标应用了制定attribute的多个实例,抛出异常AmbiguousMatchException. 因此该方法通常用于AllowMultiple=false的attribute

     最后的例子中展示了如何使用这些方法。

2.   上面的方法在检测时进行了attribute对象的构造(需要反序列化),这样有可能调用set访问器和构造方法,可能出现安全风险(未知代码在AppDomain中运行)。因此可以使用CustomAttributeData类中定的静态方法进行检测

 public override string ToString()
{
//在子类中对父类中的方法进行重写,使用不创建attribute对象不执行代码(反序列化)的方法
StringBuilder value = new StringBuilder();
if (!this.GetType().IsClass)
return value.ToString();
PropertyInfo[] properties = this.GetType().GetProperties(); foreach (var property in properties)
{
string propertyName = property.Name;
IList<CustomAttributeData> list = CustomAttributeData.GetCustomAttributes(property);
foreach (var item in list)
{
if (item.Constructor.DeclaringType == typeof(DisplayNameAttribute))
{
Console.Write("This property applies DisplayNameAttribute.");
}
}
}
return base.ToString();
}
  • 条件attribute

应用attribute时生成元数据,如果想让attribute在编译是不生成元数据可以使用条件编译,下面是例子

 #define Specify
//#define UnSpecify namespace Attribute
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Diagnostics; public class Pepople
{
[DisplayName("姓名")]
[TestDemoAttribute]
public string Name { get; set; }
} public class Man : Pepople
{
[DisplayName("年龄")]
public int Age { get; set; } public float Height { get; set; }
} [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, Inherited = false)]
[Conditional("Specify")]
public class DisplayNameAttribute : Attribute
{
public string PropertyName { get; set; } public DisplayNameAttribute()
{ } public DisplayNameAttribute(string propertyName)
{
this.PropertyName = propertyName;
}
} [Conditional("UnSpecify")]
public class TestDemoAttribute : Attribute
{ }
}
条件attribute

 注意:赘述一句,在C#中进行预定义时,必须在文件在最前面

我们用ildasm查看元数据得知,TestDemoAttribute 没有被编译成员数据,而DisplayNameAttribute被编译成了元数据

  • 实例

对上面提到的知识写了个例子,以便加强知识的理解运用。

 #define Specify
//#define UnSpecify namespace Attribute
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Diagnostics; public class Pepople
{
[DisplayName("姓名")]
[TestDemoAttribute]
public string Name { get; set; } public override string ToString()
{
StringBuilder value = new StringBuilder();
if (!this.GetType().IsClass)
return value.ToString();
PropertyInfo[] properties = this.GetType().GetProperties(); foreach (var property in properties)
{
string propertyName = property.Name;
if (property.IsDefined(typeof(DisplayNameAttribute), false))
{
DisplayNameAttribute attr = (DisplayNameAttribute)Attribute.GetCustomAttribute(property, typeof(DisplayNameAttribute));
if (attr != null)
{
propertyName = attr.PropertyName;
}
}
value.Append(propertyName);
value.Append("\t");
value.Append(property.GetValue(this, null));
value.Append("\n\r");
} return value.ToString();
}
} public class Man : Pepople
{
[DisplayName("年龄")]
public int Age { get; set; } public float Height { get; set; }
} public static class OutputerClass
{
public static string StringClass(object obj)
{
StringBuilder value = new StringBuilder();
if (!obj.GetType().IsClass)
return value.ToString();
PropertyInfo[] properties = obj.GetType().GetProperties(); foreach (var property in properties)
{
DisplayNameAttribute attr = (DisplayNameAttribute)Attribute.GetCustomAttribute(property, typeof(DisplayNameAttribute));
if (attr != null)
{
value.Append(attr.PropertyName);
value.Append("\t");
value.Append(property.GetValue(obj, null));
value.Append("\n\r");
}
} return value.ToString();
}
} //可以用attributeUsage声明属性应用的范围,可以多选,多选的时候|运算即可
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, Inherited = false)]
[Conditional("Specify")]
public class DisplayNameAttribute : Attribute
{
public string PropertyName { get; set; } public DisplayNameAttribute()
{ } public DisplayNameAttribute(string propertyName)
{
this.PropertyName = propertyName;
}
} [Conditional("UnSpecify")]
public class TestDemoAttribute : Attribute
{ }
}

实例

再次深入 C# Attribute的更多相关文章

  1. C#基础---Attribute(标签) 和 reflect(反射) 应用二

    以前我有写过一篇有关,打标签和反射的应用,主要用于类中字段的验证.下面是连接 C#基础---Attribute(标签) 和 reflect(反射) 应用. 这个项目迭代发现公司项目里面发现老代码对业务 ...

  2. 有关attribute和property,以及各自对select中option的影响

    这个问题老生常谈,但是直到现在我依旧时常会把它搞混.下面列一些各自的特性.   attribute property 设置方法 option.setAttribute('selected', true ...

  3. OAF_开发系列06_实现OAF属性集的介绍和开发Attribute Set(案例)

    20150705 Created By BaoXinjian

  4. 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【外传】——Attribute Routing

    系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html 题外话:由于这个技术点是新学的,并不属于原系列,但借助了原系列的项目背景,故命名外传系列,以后也可 ...

  5. .net学习之Attribute特性和EF关键知识点

    一.Attribute特性/标签1.Attribute用来对类.属性.方法等标注额外的信息,贴一个标签简单的说,定制特性Attribute,本质上就是一个类,它为目标元素提供关联附加信息,并在运行时以 ...

  6. Attribute "lazy" with value "true" must have a value from the list "false proxy no-proxy "

    Hibernate 3.2 版本 当设置lazy="true"属性时,会产生该个异常: Attribute "lazy" with value "tr ...

  7. 深入浅出Attribute (转载)

    原文地址:http://blog.csdn.net/FantasiaX/article/details/1627694 正文: 什么是Attribute?Attribute是干什么使的?Attribu ...

  8. Flash Attribute

    参考:http://www.open-open.com/lib/view/open1397266120028.html 为解决POST/Forward/GET出现的重复提交数据问题,改用POST/Re ...

  9. C#中的Attribute和Java中的Annotation

    在之前的博客中介绍过C#的Attribute(特性),简单的说,特性主要就是利用反射技术,在运行期获取关注类的相关标注信息,然后利用这些标注信息对关注的类进行处理,最近因为工作的原因,需要看一下Jav ...

随机推荐

  1. STM32驱动ht1621b显示LCD

    这几天在写ht1621b显示LCD的程序,主芯片是Stm32f10的芯片.对于stm32和ht1621b的运用和操作本人是新手,属于赶鸭子上架,通过查看datasheet等资料和网上查看前人写的程序终 ...

  2. UGUI事件系统

    UGUI系统 将UI可能触发的事件分为12个类型,即EventTriggerType枚举的12个值. PointerEnter-- PointerExit-- PointerDown-- Pointe ...

  3. .net 在数据访问层中写一个DBhelper优化类

    复习了在学校的时候做的WinForm端的一个学生信息管理系统,用的三层架构,看了一下里面的数据优化类 这个类是用来把对数据库的操作封装成静态方法,增删改查的时候直接调用这个类,减少项目里代码的冗余和方 ...

  4. 调用ZoomEye API获取信息

    最近在提高自己编程能力,拿一些实用的小工具练下.该脚本为python语言,主要涉及模块urllib,json,os模块. 功能:调用ZoomEye API获取信息 import urllib.requ ...

  5. Dev的GridControl控件选择框的使用

    先介绍环境:VS2010,dev11.2 想要达到的效果:,当单击某一行时前面的选择框选中. 在网上找了不少,但是感觉跟我想的做法很不一样(有很多都是再另外添加一个什么CheckBox,这个我在Dev ...

  6. 使用NCoding归档进行存储数据时候报错

    问题:Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Demo1.UserInfo ...

  7. Java版经典兔子繁殖迭代问题——斐波那契(Fibonacci)数列

    /** * 题目: * 有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子. * 假如兔子都不死,问经过month个月后,兔子的总数为多少对? */ public ...

  8. 微信小程序文档解读(一)--api提供支持有哪些

    本文重点在于小程序API提供的微信功能支持及获取用户信息的解读,具体的用法和调用不在本文讨论范围之内,文章基于20161222版文档解读 API官方文档原文链接 小程序API官方定义: 框架提供丰富的 ...

  9. win8,win10安装mysql

    以管理员身份进到命令窗口后,找到要安装的文件,执行msiexec /package mysql-installer-community-5.7.16.0.msi   回车即可

  10. sudo命令出错 must set be suid

    特殊权限 4,2 ,1 4  suid,控制用户执行的文件,以文件所属用户的身份执行.当一个可执行的文件拥有suid时,会将文件拥有者的x位变成s(---s--x--x),这时称为set uid,简写 ...