C#自定义特性实例
元数据,就是C#中封装的一些类,无法修改.类成员的特性被称为元数据中的注释.
1、什么是特性
(1)属性与特性的区别
属性(Property):属性是面向对象思想里所说的封装在类里面的数据字段,Get,Set方法。
特性(Attribute): 官方解释:特性是给指定的某一声明的一则附加的声明性信息。 允许类似关键字的描述声明。它对程序中的元素进行标注,如类型、字段、方法、属性等。从.net角度看,特性是一种 类,这些类继承于System.Attribute类,用于对类、属性、方法、事件等进行描述,主要用在反射中。但从面向对象的级别看,其实Attribute是类型级别的,而不是对象级别。
Attributes和.net文件的元素据保存在一起,可以用来向运行时描述你的代码,或者在程序运行的时候影响程序的行为。
2、特性的应用
(1).net中特性用来处理多种问题,比如序列化、程序的安全特性、防止即时编译器对程序代码进行优化从而代码容易调试等等。
定植特性的本质上是一个类的元素上去添加附加信息,并在运行其通过反射得到该附加信息(在使用数据实体对象时经常用到)
(2)Attribute 作为编译器的指令时的应用
Conditional:起条件编译的作用,只有满足条件,才允许编译器对它的代码进行编译。一般在程序调试的时候使用
DllImport: 用来标记费.net的函数,表明该方法在一个外部的DLL中定义。
Obsolete: 这个属性用来标记当前的方法已经废弃,不再使用
注:Attribute是一个类,因此DllImport也是一个类,Attribute类是在编译的时候实例化,而不是像通常那样在运行时实例化。
CLSCompliant: 保证整个程序集代码遵守CLS,否则编译将报错。
3、自定义特性
使用AttributeUsage,来控制如何应用新定义的特性
[AttributeUsageAttribute(AttributeTargets.All 可以应用到任何元素
,AllowMultiple=true, 允许应用多次,我们的定值特性能否被重复放在同一个程序实体前多次。
,Inherited=false,不继承到派生
)]
特性也是一个类,必须继承于System.Attribute类,命名规范为“类名”+Attribute。不管是直接还是间接继承,都会成为一个特性类,特性类的声明定义了一种可以放置在声明之上新的特性。
public class MyselfAttribute:System.Attribute
4、自定义特性案例
以下用一个类似于Hibernate中Session的Save()方法效果,自动持久化对象信息到数据库来说明自定义特性的使用。
(1)建立Dept表
Create Table Dept(
deptNo int identity(1,1) primary key,
dname nvarchar(10) not null,
description nvarchar(100)
)
Go
-- 何问起 hovertree.com
(2)自定义特性类
/**************自定义特性类*****************/
/// <summary>
/// 作用:用来说明表名是什么
/// AttributeUsage:说明特性的目标元素是什么
/// AttributeTargets.Class:代表目标元素为Class
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
public class TableAttribute : Attribute{ /// <summary>
/// 表名
/// </summary>
public string TableName { get; set; } #region 构造方法,可选的 public TableAttribute() { }
public TableAttribute(string tableName) {
this.TableName = tableName;
} #endregion
} /**************自定义特性类*****************/
/// <summary>
/// 作用:说明列是否为自动增长列
/// </summary>
[AttributeUsage(AttributeTargets.Property)]
class IdentityAttribute: Attribute
{
/// <summary>
/// true:是; false:否
/// </summary>
public bool IsIdentity { get; set; }
} /****************实体类***************/
/// <summary>
/// 有意将类名定义成与表名不一致
/// 用Table特性来说明实体类对应的表名是什么
/// </summary>
[Table(TableName = "Dept")]
public class Department { /// <summary>
/// 部门编号,用特性标注为自动增长
/// </summary>
[Identity(IsIdentity=true)]
public int DeptNo { get; set; } /// <summary>
/// 部门名称
/// </summary>
public string Dname { get; set; } /// <summary>
/// 部门描述
/// </summary>
public string Description { get; set; } public Department( string name, string desc) {
Dname = name;
Description = desc;
}
} /****************执行持久化操作类***************/
/// <summary>
/// 执行持久化操作类
/// </summary>
public class ADOManager { /// <summary>
/// 将对象的属性值作为表中对应列的值来添加
/// </summary>
/// <param name="obj">要添加的对象</param>
public int Save(Object obj) {
//1.取得类名:代表表名,用到反射
string tableName = obj.GetType().Name;
//如果类有TableAttribute特性,在采用特性说明的类名
TableAttribute attr = Attribute.GetCustomAttribute(obj.GetType(), typeof(TableAttribute)) as TableAttribute;
if (attr != null) {//说明类加了Table特性
tableName = attr.TableName;//取得表名
} //sql语句模板:insert into Dept(deptno,dname,description) values('2','','');
StringBuilder sql = new StringBuilder("insert into ");
sql.Append(tableName);
sql.Append(" ("); //循环对象的属性名:取得列名
foreach (PropertyInfo item in obj.GetType().GetProperties()) {
//取得是否有自动增长的特性
IdentityAttribute att = Attribute.GetCustomAttribute(item, typeof(IdentityAttribute)) as IdentityAttribute;
if (att == null || !att.IsIdentity) {//没有,则添加列
sql.Append(item.Name);
sql.Append(",");
}
}
//去除最后一个逗号'
sql.Remove(sql.Length - , );
sql.Append(") values(");
//循环取出对象的属性值:为列赋值
foreach (PropertyInfo item in obj.GetType().GetProperties()) {
//取得是否有自动增长的特性
IdentityAttribute att = Attribute.GetCustomAttribute(item, typeof(IdentityAttribute)) as IdentityAttribute;
if (att == null) {//没有,则追加列的值
//GetValue():obj代表什么对象,null代表没有参数
sql.Append("'" + item.GetValue(obj, null) + "'");
sql.Append(",");
}
} //去除最后一个逗号'
sql.Remove(sql.Length - , );
sql.Append(")");
//查看完整的sql语句
Console.WriteLine(sql.ToString()); //执行sql语句
SqlConnection conn = new SqlConnection("server=.;database=test;integrated security=true");
SqlCommand comm = new SqlCommand(sql.ToString(), conn);
conn.Open();
int r = comm.ExecuteNonQuery();
conn.Close(); return r;//返回执行结果
}
}
/* 何问起 hovertree.com */
/****************测试类关键代码***************/
Department dept = new Department("开发部", "负责产品的研发");
ADOManager manager = new ADOManager();
int r = manager.Save(dept); Console.WriteLine(r==?"失败":"成功");
小结:
C#的特性类和Java中的元注释一样
特性其本质就是一个继承了Attribute的类
使用使可以省略Attribute结尾,如:TableAttribute =>> Table
特性将会影响其作用的目标元素的编译和运行过程
使用自定义特性的步骤:
1. 定义特性类,类必须直接或间接继承字Attribute类
2. 在需要用的该特性的目标元素上添加特性
3. 在使用添加了特性的类的使用,获取并使用自特定特性的信息
推荐:http://www.cnblogs.com/roucheng/p/dushubiji.html
C#自定义特性实例的更多相关文章
- 【.net 深呼吸】自定义特性(Attribute)的实现与检索方法
在.net的各个语言中,尤其是VB.NET和C#,都有特性这一东东,具体的概念,大家可以网上查,这里老周说一个非标准的概念——特性者,就是对象的附加数据.对象自然可以是类型.类型成员,以及程序集. 说 ...
- 如何获取类或属性的自定义特性(Attribute)
如何获取类或属性的自定义特性(Attribute) 问题说明: 在ActiveRecord或者其他的ORM等代码中, 我们经常可以看到自定义特性(Attribute)的存在(如下面的代码所示) [Pr ...
- 代码走查25条疑问 C# 跳转新的标签页 C#线程处理 .Net 特性 attribute 学习 ----自定义特性 看懂 ,学会 .NET 事件的正确姿势-简单版
代码走查25条疑问 代码走查(Code Review) 是一个开发人员与架构师集中讨论代码的过程.通过代码走查可以提高代码的 质量,同时减少Bug出现的几率.但是在小公司中并没有代码走查的过程在这 ...
- C# 反射通过GetCustomAttributes方法,获得自定义特性
http://blog.csdn.net/litao2/article/details/17633107 使用反射访问: 自定义属性的信息和对其进行操作的方法. 一.实例1 1.代码: 如:Syste ...
- C#反射与特性(七):自定义特性以及应用
目录 1,属性字段的赋值和读值 2,自定义特性和特性查找 2.1 特性规范和自定义特性 2.2 检索特性 3,设计一个数据验证工具 3.1 定义抽象验证特性类 3.2 实现多个自定义验证特性 3.3 ...
- Shader的自定义特性使用
使用自定义特性关键字,可以动态对Shader某一部分代码进行开关操作 shader(定义了KEYWORD1特性): 定义:#pragma shader_feature KEYWORD1 判断:#ifd ...
- C# 通过自定义特性 实现根据实体类自动创建数据库表
.Net新手通常容易把属性(Property)跟特性(Attribute)搞混,其实这是两种不同的东西 属性指的类中封装的数据字段:而特性是对类.字段.方法和属性等元素标注的声明性信息 如下代码(Id ...
- c#通过反射获取类上的自定义特性
c#通过反射获取类上的自定义特性 本文转载:http://www.cnblogs.com/jeffwongishandsome/archive/2009/11/18/1602825.html 下面这个 ...
- C#之自定义特性
在前面介绍的代码中有使用特性,这些特性都是Microsoft定义好的,作为.NET Framework类库的一部分,许多特性都得到了C#编译器的支持. .NET Frmework也允许定义自己的特性. ...
随机推荐
- 科蓝软件急招前端开发、PHP、.NET工程师
职位:前端开发 工作年限:不限 学历要求:大专 招聘人数:2 专业:不限 薪酬:面议 工作地点:浙江嘉兴.北京 岗位职责: 1.负责公司项目的UI设计: 2.负责将UI静态化 ...
- html5 Web Workers
虽然在JavaScript中有setInterval和setTimeout函数使javaScript看起来好像使多线程执行,单实际上JavaScript使单线程的,一次只能做一件事情(关于JavaSc ...
- NanoProfiler - 适合生产环境的性能监控类库 之 大数据篇
上期回顾 上一期:NanoProfiler - 适合生产环境的性能监控类库 之 基本功能篇 上次介绍了NanoProfiler的基本功能,提到,NanoProfiler实现了MiniProfiler欠 ...
- Mysql日常开发注意要点
1.MySQL存储引擎介绍 MyISAM:低版本MySQL默认的MySQL插件式存储引擎,存储文件易损坏,不支持事务.InnoDB:目前默认的MySQL存储引擎,用于事务处理应用程序,具有众多特性,包 ...
- IOS 推送-配置与代码编写
IOS 推送配置与代码编写 这里介绍IOS的推送,本文章已经在IOS6/7/8上都能运行OK,按照道理IOS9应该没问题. 大纲: 1.文章前提 2.推送介绍 3.推送文件账号设置 4.推送证书介绍 ...
- Node.js与Sails~自定义响应体responses
回到目录 在Node.js里,你可以控制请求和响应,自己可以定义自己的响应方式,如对文本如何响应,对json如何响应,对图像流如何响应等等,而这些在Sails架构里,变得更加容易和清晰了,它位于项目的 ...
- vc操作windows防火墙的方法
收藏该地址,以备不时之需. http://msdn.microsoft.com/en-us/library/aa364726.aspx
- 蒙特·卡罗算法的Python实现
一 背景 此算法诞生的背景是: 曼哈顿计划,有极大的计算需求. 计算机刚开始发展,最适合做计算. 蒙特卡洛算法理论基础是概率论,实际就是暴力计算逼近理想结果.正是在以上两个背景下,它刚好得到了极大的应 ...
- 一种利用 Cumulative Penalty 训练 L1 正则 Log-linear 模型的随机梯度下降法
Log-Linear 模型(也叫做最大熵模型)是 NLP 领域中使用最为广泛的模型之一,其训练常采用最大似然准则,且为防止过拟合,往往在目标函数中加入(可以产生稀疏性的) L1 正则.但对于这种带 L ...
- iOS-地图报错超出了经纬度范围Invalid Region
做地图定位的时候,使用一下代码 // 经纬度 CLLocationDegrees latitude = [storeDict[@"lat"] doubleValue]; CLLoc ...