.NET简谈特性(代码属性)

由于很久没有写关于基础知识的东西了,今天来总结一下关于.NET平台中的代码属性的概念;只是基础介绍,文章的本意是带领初学者学会使用特性,而不是讨论高深的底层技术;[王清培版权所有,转载请给出署名]

1.什么叫特性Attribute

特性对一般.NET编程人员来说并不陌生,自从我们开始接触C#语言的时候,我们多多少少已经接触了关于特性的使用;但是对于初学者来说真的不明白特性的意义,特性到底是属于类还是类实例,这些概念搞不清楚对理解代码的逻辑真的很顺利;这篇文章我将带您来了解特性的作用,其实特性的真的很方便;至少我认为自从我懂特性之后,我的代码便的更加的人性化,程序的结构清晰易懂,所以本人在写代码的时候经常喜欢用一些能够简单明了的表达对象的特点的风格;

其实特性Attribute就是一段代码属性,附加在我们定义的对象上的,特性属于对象而不是实例,这个概念要注意;为什么需要特性,我想任何一个开发人员都不需要问为什么,因为它的好处我们是拍手叫绝的,好东西为什么不要呢;之所以你没感觉到是因为朋友你还没发现他的优点;我们还是拿代码例子来讲吧,这样便于我们双向交流;

2.实例代码学习

using System;
using System.Collections.Generic;
using System.Text;

namespace AttributeTest
{
    [TableName(Name = "Tb_UserName")]
    public class M_UserName
    {

    }
}

这段代码里,我有一个M_UserName类,在类的上面我加了一个TableName的特性,这个特性是用来标识我这个类对应着数据库表的名称,这样的应用一般都会在ORM中出现;TableName是我们自己定义的一个特性,这样的特性不能影响系统的编译行为,而系统的特性会改变代码的编译行为,这样的编译控制是有必要的,比如我们在进行.NET安全编程的时候,经常会用到SecurityPermissionAttribute特性控制代码的安全执行逻辑,操作系统的API最重要的一个作用就是权限控制,以免大家一起进入内核;如果不用特性进行标记,那么所有的方法都会被统一编译无法控制;[王清培版权所有,转载请给出署名]

我们回到TableName特性,特性是一中特殊的类型,这个类型继承自Attribute对象;

using System;
using System.Collections.Generic;
using System.Text;

namespace AttributeTest
{
    /// <summary>
    /// 数据库表的名称
    /// </summary>
    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
    public class TableName : Attribute
    {
        /// <summary>
        /// 名称
        /// </summary>
        public string Name { get; set; }
    }
}

我们定义的特性还需要用系统的AttributeUsage特性进行标记,系统好将我们自己定义的特性当成特殊的类型处理;在此穿插一句,特性也是属于类类型,只不过是一种特殊的类型,这中类型是需要我们用系统特性进行说明的,这样系统在编译的时候才会将我们的特性进行元数据的区分,我们通过反射就可以把这个特殊的元数据拿到;

也许你会问,我这样标记了一个类的特性有什么用呢,当然有用,我们下面通过反射来进行动态读取对象的特性;特性属于类类型也就是属于Type,我们是通过类型获取而不是实例获取特性;

using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;

namespace AttributeTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Type type = typeof(M_UserName);//通过typeof方法获取Type对象

            object[] obj = type.GetCustomAttributes(typeof(TableName), false);//通过Type对象获取指定特性

            TableName name = obj[0] as TableName;

            Console.WriteLine(name.Name);

            Console.ReadLine();
        }
    }
}

这样我们就拿到了特性所标记的值,其实你可以把特性当成是一种静态类,当我们获取特性的时候,系统会将特性类进行加载到内存中,我不知道特性类的数据在内存中的布局是什么样的,但是对我们刚开始学习使用的时候,可以这么先理解;

总结:特性是一段代码属性,是一种特殊的类,在编译的时候以特殊的身份存在于元数据中,当我们获取它的时候,系统加载到内存中。特性属于类,不属于类实例;[王清培版权所有,转载请给出署名]

时间: 2024-09-15 18:43:07

.NET简谈特性(代码属性)的相关文章

.NET简谈互操作(三:基础知识之DllImport特性)

互操作系列文章: .NET简谈互操作(一:开篇介绍) .NET简谈互操作(二:先睹为快) .NET简谈互操作(三:基础知识之DllImport特性) .NET简谈互操作(四:基础知识之释放非托管内存) .NET简谈互操作(五:基础知识之Dynamic平台调用) .NET简谈互操作(六:基础知识之提升平台调用性能) .NET简谈互操作(七:数据封送之介绍) 我们继续.NET互操作学习,上一篇文章中我们介绍了托管代码怎么与非托管代码C++之间的互操作:要想在托管代码中成功的进行非托管调用,要注意的细

.NET简谈组件程序设计之(手动同步)

在上一篇文章".NET简谈组件程序设计之(上下文与同步域)"中,我们学习了关于一些上下文和同步域的概念,可以利用这两个技术来进行自动同步. 今天我们主要学习怎么手动来执行同步,能从更小的粒度进行封锁,以达到最大程度的吞吐量.[王清培版权所有,转载请给出署名] 我们知道线程是进程的运行实体,进程是资源分配单位,而线程是执行单位.照书上所说,线程是程序的执行路径,当我们分配一个线程的时候,要确定线程的执行路径是什么,也就是代码中的ThreadStart委托所指向的入口点方法. 一旦我们手动

.NET简谈互操作(五:基础知识之Dynamic平台调用)

互操作系列文章: .NET简谈互操作(一:开篇介绍) .NET简谈互操作(二:先睹为快) .NET简谈互操作(三:基础知识之DllImport特性) .NET简谈互操作(四:基础知识之Dispose非托管内存) .NET简谈互操作(五:基础知识之Dynamic平台调用) .NET简谈互操作(六:基础知识之提升平台调用性能) .NET简谈互操作(七:数据封送之介绍) 我们继续.NET互操作学习.在上篇文章中我们学习了关于托管与非托管内存Dispose(释放)问题:下面我们继续学习基础知识中的Dyn

.NET简谈接口

自从面向对象开发方式的出现,抽象的概念就开始日新月异的发展,面向对象编程.面向接口编程.面向组件编程等等:这一系列的概念都是软件工程所追求的思想范畴,高类聚低耦合. 今天我要简谈的是面向对象里面非常重要的也是非常抽象的概念,接口.谈起接口多少人曾经为之痛苦过,尤其是一些刚入门的开发人员(包括小弟),百思不得其解,啥叫接口,接口能干嘛用,用不用有什么区别:等等问题困扰着,这些问题不解决不弄明白,很难在面向对象领域混,更别谈面向对象开发了,可能有人认为面向对象开发就是麻烦我不用一样也能开发,开发一个

.NET简谈组件程序设计之(渗入序列化过程)

在本人的上一篇文章".NET简谈组件程序设计之(初识序列化.持久化) "中,我们基本上了解了什么叫序列化和持久化.通过系统为我们提供的服务,我们可以很方便的进行二进制序列化.SOAP协议序列化. 今天这篇文章是来讲解怎么运用一些高级的功能,在序列化.反序列化过程中进行一些控制.[王清培版权所有,转载请给出署名] 这里穿插一句题外话:其实在我们自己编写组件的时候真的有好多东西可以借鉴.NET平台的一些优点,它的功能都不是死的,可以订阅.可以切入,在我们编写组件的时候,我们其实也要好好考虑

.NET简谈互操作(二:先睹为快)

互操作系列文章: .NET简谈互操作(一:开篇介绍) .NET简谈互操作(二:先睹为快) .NET简谈互操作(三:基础知识之DllImport特性) .NET简谈互操作(四:基础知识之释放非托管内存) .NET简谈互操作(五:基础知识之Dynamic平台调用) .NET简谈互操作(六:基础知识之提升平台调用性能) .NET简谈互操作(七:数据封送之介绍) 我们继续.NET互操作学习,为了揭开互操作的神秘面纱,今天这篇文章我们就来先睹为快,让我们先来做个例子,基础的东西,我们陆续进行讲解:由于互操

.NET简谈事务、分布式事务处理

在本人的 " .NET简谈事务本质论"一文中我们从整体上了解了事务模型,在我们脑子里能有一个全局的事务处理结构,消除对数据库事务的依赖理解,重新认识事务编程模型. 今天这篇文章我们将使用.NET C#来进行事务性编程,从浅显.简单的本地事务开始,也就是我们用的最多的ADO.NET事务处理,然后我们逐渐扩大事务处理范围,包括对分布式事务处理的使用,多线程事务处理的使用.   数据库事务处理 数据库事务处理我们基本都很熟悉了,begin Transaction --end Transact

.NET简谈组件程序设计之(初识NetRemoting)

在本人的".NET简谈组件程序设计之(初识远程调用)  "一文中,我们了解到什么是远程调用或者说在.NET平台上远程调用是什么样子的,可能和偏低层(Socket\Rpc)的远程调用有点距离.这只是系统为我们封装了假象而已,看不见不代表没有这逻辑,是为我们减轻了劳动负担.[王清培版权所有,转载请给出署名] 这篇文章我们来简单的了解一下在.NET平台上有一个强有力的远程调用武器,也是上一篇文章中我一笔带过的远程英雄.NetRemoting. 其实在.NET平台里面到处都能看见Remotin

.NET简谈互操作(六:基础知识之提升平台调用性能)

互操作系列文章: .NET简谈互操作(一:开篇介绍) .NET简谈互操作(二:先睹为快) .NET简谈互操作(三:基础知识之DllImport特性) .NET简谈互操作(四:基础知识之Dispose非托管内存) .NET简谈互操作(五:基础知识之Dynamic平台调用) .NET简谈互操作(六:基础知识之提升平台调用性能) .NET简谈互操作(七:数据封送之介绍) 我们继续.NET互操作学习.本篇文章我们将来学习互操作基础知识中的最后一个知识点"提升平台调用的性能": 在于非托管函数进