c#attribute是否影响c程序性能优化 pdf 性能

C#属性(attribute)
C#属性(attribute)
Windows10用户联盟QQ群:
属性是用来传递信息到运行有关像类,方法,结构,枚举,集等各种元素的行为,在你的程序中声明的标签。可以通过使用属性添加声明信息的程序。声明性标记由正方形描绘([])置于它被用于元件上方括号。
属性用于添加元数据,如编译器的指令和其他信息,例如注释,描述,方法和类的程序。 .NET Framework提供了两种类型的属性:预先定义的属性和定制属性。
指定属性的语法如下:
[attribute(positional_parameters, name_parameter = value, ...)]
属性的名称和值在方括号内指定的元素该属性的应用之前。位置参数指定的基本信息和名称参数指定的可选信息。
预定义的属性
.NET Framework提供了三个预定义的属性:
AttributeUsage
Conditional
AttributeUsage:
预先定义的属性AttributeUsage描述了如何自定义属性的类可以使用。它指定该属性可应用的项目类型。
用于指定该属性的语法如下:
[AttributeUsage(
AllowMultiple=allowmultiple,
Inherited=inherited
参数validon指明该属性可以放置在语言元素。它是一个枚举AttributeTargets的值的组合。默认值是AttributeTargets.All。
参数允许多个(可选)提供值这个属性,一个布尔值的AllowMultiple属性。如果是true,该属性为多用途。默认值为false(一次性使用)。
继承的参数(可选)提供值这个属性,一个布尔值的继承属性。如果是true,该属性由派生类继承。默认值是false(而不是继承)。
[AttributeUsage(AttributeTargets.Class |
AttributeTargets.Constructor |
AttributeTargets.Feild |
AttributeTargets.Method |
AttributeTargets.Property,
AllowMultiple = true)]
此预定义属性标志着一个条件方法的执行依赖于一个指定的预处理标识符。
它引起的方法调用条件编译,根据所指定的值,如调试或跟踪。例如,它在调试代码显示变量的值。
用于指定该属性的语法如下:
[Conditional(
conditionalSymbol
[Conditional(&DEBUG&)]
下面的例子演示了属性:
#define DEBUG
using System;
using System.Diagnostics;
public class Myclass
[Conditional(&DEBUG&)]
public static void Message(string msg)
Console.WriteLine(msg);
class Test
static void function1()
Myclass.Message(&In Function 1.&);
function2();
static void function2()
Myclass.Message(&In Function 2.&);
public static void Main()
Myclass.Message(&In Main function.&);
function1();
Console.ReadKey();
让我们编译和运行上面的程序,这将产生以下结果:
In Main function
In Function 1
In Function 2
这个预定义的属性标记不应该被使用的程序的实体。它使您能够告诉编译器丢弃特定的目标元素。例如,当一个新的方法正在使用中的一个类,仍然要保留旧方法的类,但可以标记,代替旧的方法是通过使用显示一个消息,这个新方法已经过时。
用于指定该属性的语法如下:
[Obsolete(
[Obsolete(
该参数的消息,是一个描述原因的字符串显示为什么项目已经过时,用什么来代替。
该参数是iserror,是一个布尔值。如果它的值是true,编译器应该把使用的项目作为一个错误对待。默认值为false(编译器生成一个警告)。
下面的程序说明了这一点:
using System;
public class MyClass
[Obsolete(&Don't use OldMethod, use NewMethod instead&, true)]
static void OldMethod()
Console.WriteLine(&It is the old method&);
static void NewMethod()
Console.WriteLine(&It is the new method&);
public static void Main()
OldMethod();
当您尝试编译程序,编译器给出了一个错误信息,如下:
Don't use OldMethod, use NewMethod instead
创建自定义属性
.Net框架允许创建可用于存储信息的声明,并可以检索在运行时间自定义属性。这个信息可以与根据设计标准和应用的需要的任何目标元素。
创建和使用自定义属性包括四个步骤:
声明一个自定义属性
构造自定义属性
应用自定义属性的目标程序元素
通过反射访问属性
最后一步需要编写一个简单的程序来读取通过元数据来寻找各种符号。元数据是关于用于描述其他数据的数据或信息的数据。这个程序应该使用反射访问属性在运行时。为此,反射我们将在下一章中讨论。
声明自定义属性
一个新的自定义属性应该是从System.Attribute类派生的。例如,
//a custom attribute BugFix to be assigned to a class and its members
[AttributeUsage(AttributeTargets.Class |
AttributeTargets.Constructor |
AttributeTargets.Field |
AttributeTargets.Method |
AttributeTargets.Property,
AllowMultiple = true)]
public class DeBugInfo : System.Attribute
在上面的代码中,我们已经声明命名的自定义属性为&DeBugInfo.
构造自定义属性
让我们构建名为DeBugInfo的自定义属性,这将存储由调试任何程序中获得的信息。它存储了以下信息:
错误的代码数量
发现的错误开发人员名称
代码的最后一次审查的日期
存储开发人员的备注字符串消息
DeBugInfo类将有三个私有属性存储前三个信息,公共属性用于存储信息。所以这个bug数量,开发者的姓名和审查日期是DeBugInfo类的定位参数;消息将是一个可选或命名参数。
每个属性必须至少有一个构造函数。参数的位置应通过构造函数来传递。下面的代码显示了DeBugInfo类:
//a custom attribute BugFix to be assigned to a class and its members
[AttributeUsage(AttributeTargets.Class |
AttributeTargets.Constructor |
AttributeTargets.Field |
AttributeTargets.Method |
AttributeTargets.Property,
AllowMultiple = true)]
public class DeBugInfo : System.Attribute
private int bugNo;
private string developer;
private string lastReview;
public string message;
public DeBugInfo(int bg, string dev, string d)
this.bugNo = bg;
this.developer = dev;
this.lastReview = d;
public int BugNo
return bugNo;
public string Developer
return developer;
public string LastReview
return lastReview;
public string Message
return message;
message = value;
应用自定义属性
属性应用于通过立即它的目标之前将其放置:
[DeBugInfo(45, &Zara Ali&, &12/8/2012&, Message = &Return type mismatch&)]
[DeBugInfo(49, &Nuha Ali&, &10/10/2012&, Message = &Unused variable&)]
class Rectangle
//member variables
protected double length;
protected double width;
public Rectangle(double l, double w)
length = l;
width = w;
[DeBugInfo(55, &Zara Ali&, &19/10/2012&,
Message = &Return type mismatch&)]
public double GetArea()
return length * width;
[DeBugInfo(56, &Zara Ali&, &19/10/2012&)]
public void Display()
Console.WriteLine(&Length: {0}&, length);
Console.WriteLine(&Width: {0}&, width);
Console.WriteLine(&Area: {0}&, GetArea());
在下一章中,我们将检索使用反射类对象,这些属性信息。
标签:&&&&&&&&&&&&&&国之画&&&&&&
版权所有 京ICP备号-2
迷上了代码!C# .NET开发里的attribute是编译期还是运行期魔法?_百度知道这篇文章主要讲一下C#里面Attribute的使用方法及其可能的应用场景。比如你把玩家的血量、攻击、防御等属性写到枚举里面。然后界面可能有很多地方要根据这个枚举获取属性的描述文本。比如你做网络框架的时候,一个协议号对应一个类的处理或者一个方法。比如你做ORM,一个类的属性是否映射持久化文件中的属性,映射过去的属性名是什么。1、什么是Attribute如果用过Java的Annotation的同学,可以把Attribute当成Annotation来看待。还不了解Attribute的同学不用急,我们看一下官方的解释:Attribute class associates predefined
system information or user-defined custom information with a target
element. A target element can be an assembly, class, constructor,
delegate, enum, event, field, interface, method, portable executable
file module, parameter, property, return value, struct, or another
attribute.Information provided by an attribute is also known as metadata. Metadata
can be examined at run time by your application to control how your
program processes data, or before run time by external tools to control
how your application itself is processed or maintained. For example, the
.NET Framework predefines and uses attribute types to control run-time
behavior, and some programming languages use attribute types to
represent language features not directly supported by the .NET Framework
common type system.Attribute class. Attributes can be applied t
multiple attributes can be applied to the and
attributes can be inherited by an element derived from a target element.
AttributeTargets class to specify the target element to which the
attribute is applied.Attribute class provides convenient methods to retrieve and test custom
attributes. Applying Attributes and Extending Metadata Using Attributes.翻译过来就是:
Attribute类可以把目标元素和一个预定义的信息或者是用户自定义信息关联起来。这里的目标元素可以是
assembly,class,constructor,delegate,enum,event,field,interface,method,可执
行文件模块,parameter,property,return value,struct或其它的Attribute。
Attribute提供的信息也被称为元数据(metadata)。元数据能用于在运行时控制怎样访问你的程序数据,或者在运行前通过额外的工具来控制怎
样处理你的程序或部署它。例如.NET
Framework预定义并使用attribute去控制运行时行为,一些编程语言使用attribute类型来描述.NET
Framework中通用类型不直接支持的语言特性。
所有的Attribute类型直接或间接从Attribute类继承。Attribute能应用到任何target元素;多个Attribute能应用到相同的元素;
Attribute类提供遍历的方法去取出和测试自定义Attribute。更多关于Attribute的信息,可以看Applying Attributes和Extending Metadata Using Attributes。如果你看了官方的解释不明白,看了我的翻译也不明白。也没事。。。我们接下来举个例子看看Attribute能做啥。2、用Attribute将枚举和一个描述文本绑定在一起假设有这个枚举public enum Properties{
/// &summary&
/// &/summary&
/// &summary&
/// 物理攻击
/// &/summary&
PhyAtk = 2,
/// &summary&
/// 物理防御
/// &/summary&
PhyDef = 3,
/// &summary&
/// 法术攻击
/// &/summary&
MagAtk = 4,
/// &summary&
/// 法术防御
/// &/summary&
MagDef = 5}注意:如果含中文的代码编译报“Newline in constant”的错。那么请将文件的编码保存为“带BOM的UTF-8”。VS中可以在“文件”-“高级保存选项”,然后选择编码下拉中选择。然后你现在想要根据枚举来获得中文描述:比如传入:Properties.MagDef返回“法术防御”。最原始的做法:public class PropertiesUtils{
public static string GetDescByProperties(Properties p)
switch (p)
case Properties.HP:
return &血量&;
case Properties.PhyAtk:
return &物理攻击&;
case Properties.PhyDef:
return &物理防御&;
case Properties.MagAtk:
return &法术攻击&;
case Properties.MagDef:
return &法术防御&;
return &未知属性:& +
}}这样确实可以解决问题,但是我们可以用Attribute来做的更好。可以做的更好干嘛不呢?先定义一个用于存储描述文本的Attribute。[System.AttributeUsage(System.AttributeTargets.Field | System.AttributeTargets.Enum)]public class PropertiesDesc : System.Attribute{
public string Desc { } }没错,看起来是不是觉得很简单。然后我们就可以把上面定义的PropertiesDesc加到Properties上面,像这样:public enum Properties{
[PropertiesDesc(&血量&)]
[PropertiesDesc(&物理攻击&)]
PhyAtk = 2,
[PropertiesDesc(&物理防御&)]
PhyDef = 3,
[PropertiesDesc(&法术攻击&)]
MagAtk = 4,
[PropertiesDesc(&法术防御&)]
MagDef = 5}OK。这样,我们相当于就把一个文本描述信息通过Attribute关联到我们的枚举属性了。那么怎样获取?我们来重写之前的PropertiesUtils类。public class PropertiesUtils{
public static string GetDescByProperties(Properties p)
Type type = p.GetType();
FieldInfo[] fields = type.GetFields();
foreach (FieldInfo field in fields)
if (field.Name.Equals(p.ToString()))
object[] objs = field.GetCustomAttributes(typeof(PropertiesDesc), true);
if (objs != null && objs.Length & 0)
return ((PropertiesDesc)objs[0]).D
return p.ToString() + &没有附加PropertiesDesc信息&;
return &No Such field : &+p;
}}可以看到。这里面已经不用自己去判断哪个枚举值返回哪个字符串描述了。而是获取这个枚举域的PropertiesDesc对象。然后返回它的Desc属性。当然,你还可以把上面的代码改成通用的,把Properties改成一个Type,这样就可以处理所有的枚举。然后还可以在查找PropertiesDesc的位置增加一个缓存。根据Type和字段的Name做缓存。改完后代码如下:public class PropertiesUtils{
static Dictionary&Type, Dictionary&string, string&& cache = new Dictionary&Type, Dictionary&string, string&&();
public static string GetDescByProperties(object p)
var type = p.GetType();
if (!cache.ContainsKey(type))
Cache(type);
var fieldNameToDesc = cache[type];
var fieldName = p.ToString();
return fieldNameToDesc.ContainsKey(fieldName) ? fieldNameToDesc[fieldName] : string.Format(&Can not found such desc for field `{0}` in type `{1}`&, fieldName, type.Name);
private static void Cache(Type type)
var dict = new Dictionary&string, string&();
cache.Add(type, dict);
var fields = type.GetFields();
foreach (var field in fields)
var objs = field.GetCustomAttributes(typeof(PropertiesDesc), true);
if (objs.Length & 0)
dict.Add(field.Name, ((PropertiesDesc)objs[0]).Desc);
}}看看Cache方法,里面居然指定了PropertiesDesc!那不是不能通用这个缓存器了!那不行。我们再优化下代码,用泛型来处理这事。3、泛型优化缓存器既然是通用的,那我就不叫PropertiesUtils了。改叫AttributeUtil吧。代码如下:public class AttributeUtils{
static Dictionary&Type, Dictionary&string, string&& cache = new Dictionary&Type, Dictionary&string, string&&();
public static string GetDescByProperties&T&(object p)
var type = p.GetType();
if (!cache.ContainsKey(type))
Cache&T&(type);
var fieldNameToDesc = cache[type];
var fieldName = p.ToString();
return fieldNameToDesc.ContainsKey(fieldName) ? fieldNameToDesc[fieldName] : string.Format(&Can not found such desc for field `{0}` in type `{1}`&, fieldName, type.Name);
private static void Cache&T&(Type type)
var dict = new Dictionary&string, string&();
cache.Add(type, dict);
var fields = type.GetFields();
foreach (var field in fields)
var objs = field.GetCustomAttributes(typeof(T), true);
if (objs.Length & 0)
T obj = (T)objs[0];
Type attrType = obj.GetType();
PropertyInfo pi = attrType.GetProperty(&Desc&);
UnityEngine.Debug.Log(pi);
dict.Add(field.Name, pi.GetValue(obj, null).ToString());
}}使用这个通用工具来获取描述的时候要注意,枚举上面可以定义不同的Attribute来获取描述信息,但描述信息必须保存在一个叫Desc的
Property里面。如果你连这个名字也想自定义,那也可以增加一个参数来获取Property的名字即可。这个留给有需要的读者自己实现了。增加这个
特性都不用增加代码行数的-_-。修改后只要这样调用就可以了。Debug.Log(PropertiesUtils.GetDescByProperties&PropertiesDesc&(Properties.HP));Debug.Log(PropertiesUtils.GetDescByProperties&PropertiesDesc&(Properties.PhyAtk));4、还能干什么?
Attribute能干的事情太多了,比如你写了个类,想做ORM映射,里面有些字段不想映射到表,有些想映射到表。有些字段可能名字和表的字段不一样。这时候你就可以通过Attribute来标识哪个字段需要被映射,映射到数据库哪个字段。等等。
做过网络框架的同学也应该比较熟悉的一个应用,使用Attribute来做自动的消息派发。
总之,Attribute可以做很多自动化的事情,就看你怎么用了。Unity3D教程手册(unitymanual) 
 文章为作者独立观点,不代表微头条立场
的最新文章
本来想分析MarkUX框架的代码,但是需要购买,暂时就放下了,恰巧遇到PreGUI几乎雷同的设计思路。那就直接拿来分析吧。此文是我读此框架的笔记,外行看热闹内行看门道至于能理解多少就见仁见智了,如果我没理解的地方还请不吝指出。UE4 HTC VIVE - 房产漫游制作教程-基础篇本文主要介绍了有关镜子的制作,先把实现部分写出来,并把思路传授给大家....你知道有能力胜任和精通之间的区别是什么吗?据说,某互联网公司招了个日本人做研发,上班第一天就对部门同事说:“我在日本工作时是个加班狂,每天都很晚回家,希望大家跟上我的步伐。”一个月之后他辞职回日本了,扔下一句话:“你们这样加班,经常睡在公司是很不人道的。”如果我们都不知道高级程序员到底是个什么样子,那我又该怎么朝这个目标努力?”VR元年炒了又炒,从2014年初到2016年下半年,历时2年的时间,市场不温不火,优秀内容依然稀缺。近日游戏Gear VR游戏《Bait!》于三月份登陆Oculus Home,在不到5个月的时间里,游戏的下载量已经超过了70万份。我遇到的大多数开发人员都不怎么热衷于测试。我喜欢测试,并且比起编写新的代码,愉快地花更多的时间在测试中。我认为,正是因为专注于测试,我才可以花更少的时间来编写新的代码或修复bug,并且非常有成效本篇中,东方教主要介绍下“多卡交互”,顾名思义,同时识别多张识别图,并产生交互效果。使用HoloLens时,shell是由你周围的世界和来自系统的全息图像构成。我们将这种空间成为混合世界......涂涂乐算是比较成功的AR产品,东方教主几乎分为美术篇和程序篇和大家聊一聊涂涂乐。UGUI制作流程和优化方案...美国《赫芬顿邮报》网站刚刚登载了一名女程序员的文章。该文章讲述了她作为女程序员在职场生活中所感受到的孤独,并分析了这种孤独感产生的五大原因。好的代码,就像是好的笑话——无需解释就能让别人明白。如果你的代码能够做到不解自明,在大多数时候,你根本无需为其配备说明文档。无缝加载一般适用于地图较大的游戏,即仅加载我们看得到的地图,如果走远,这个地图就会被释放,虽然Unity优化很好,看不到的不会被渲染,但是内存仍然是有占用的,用无缝加载能大大减少场景占用的内存,这里我只讲比较简单的2D的无缝加载。项目统一构建了标准、规范,有效保证了界面的一致性,但是代码质量的提高却不是那么简单的事情。TechCrunch 上海峰会黑客马拉松的现场,我的同事提到一个比较疑惑的现象:为什么现场的“黑客”们人手一部苹果电脑?程序员都偏爱 Mac 吗?跟随我用Vuforia和Unity建立一个AR示例。并且这一切都是免费的。Unity中经常有对象或预制体,Unity虽然已经提供了Copy Component这个功能,但是想要把某个预制体或对象的组件全部都拷贝到某个新的对象上,这个就不太灵光了。有人问Unigine怎么打包加密,所以写篇Unigine快速打包成ung文件来分享给大家。我时常在想,软件开发人员在某些方面和喜鹊——一种臭名昭着地喜欢偷发亮的物品来装饰它们巢穴的鸟类非常类似。像喜鹊,从定义上说明软件开发人员是一种异常聪明,又有好奇心的动物。但是,我们非常非常容易因为闪亮的新玩具而分心。程序猿,这个字汇在近几年开始渐渐被大众所熟知。在外界看来,这一直是个特殊的群体,社会上也给程序猿贴了很多的标签,内向、屌丝、苦逼、裤衩、拖鞋等等。在他们的心中,程序猿是这样的。北京时间4月7日, 微软官方博客宣布发布Visual Studio Tools for unity 2.0 无数人追着手游的热潮来到这里,烧光了热情和积蓄,最后黯然地离开2014年上半年的成都天府软件园,汇集了大大小今天。蛮牛邀请我写点干货,注册蛮牛好些年了。还没写过技术文章呢。都是在自己博客写。今天就先写第一篇吧。这个内在编程这一行,我已经干了20多年了。至今为止,我也差不多写过六七门编程导论课程,教授时间总计超过1000小时游戏蛮牛2016虚拟现实开发者报告!最近因为项目上的需要,用到了GearVR作为开发设备。从此就开启了填坑模式,下面我就要将我在GearVR上开发所碰到的问题以及解决办法详细的做一个介绍。比盒子高级点的S6+GearVR整体来说效果确实好不少。之前只接触过GoogleCardboard SDK ,网上GearVR似乎没有比较详细的教程头一次打包整整耗掉了我一个晚上的时间。开始进入主题,手把手教您打一个GearVR包。你会怎么纪念逝去的亲友?将他的照片放在桌上,还是每天复习他的教诲?国外的游戏开发商 Crate Entertainment 为了纪念一位热爱游戏的父亲,采取极具创意的方式:让他成为游戏里的 NPC,与他心仪的游戏永远相伴。看帖子标题是否觉得有些说不出来的味道呢?但是游戏里又各种地方可以用到,大家只有按照自己理解来用吧,我暂且叫他公告列表?通告信息?满满干货哦~今天要与大家分享的是目标屏幕位置追踪显示,或许大家不太好理解,下面将提供我的一个思路。附载测试工程项目包哦~我们常用的UI都是由大堆的UI通过层级堆叠出来的。那怎么实现这种UI界面显示3D模型可以自由徐旋转运动的功能呢。RenderTexture就是一种很好用的方法。教程以Unity引擎为环境 ,重点放在Cg语言的学习和经典光照的计算上。教程以Unity引擎为环境 ,重点放在Cg语言的学习和经典光照的计算上。教程以Unity引擎为环境 ,重点放在Cg语言的学习和经典光照的计算上。教程以Unity引擎为环境 ,重点放在Cg语言的学习和经典光照的计算上。为了突破难点,作者铺助了大量图文课件几乎所有程序员都曾经产生过一种错觉认为再过几个小时哥就能搞定!...教程以Unity引擎为环境 ,重点放在Cg语言的学习和经典光照的计算上。为了突破难点,作者铺助了大量图文课件教程以Unity引擎为环境 ,重点放在Cg语言的学习和经典光照的计算上。为了突破难点,作者铺助了大量图文课件教程以Unity引擎为环境 ,重点放在Cg语言的学习和经典光照的计算上。为了突破难点,作者铺助了大量图文课件教程以Unity引擎为环境 ,重点放在Cg语言的学习和经典光照的计算上。为了突破难点,作者铺助了大量图文课件程序员,你就像那漆黑夜里的萤火虫,一举一动都深深出卖了你。程序员是什么物种?教程以Unity引擎为环境 ,重点放在Cg语言的学习和经典光照的计算上。为了突破难点,作者铺助了大量图文课件程序员自己也常说,工作效率最高的时候总是在深夜,不是凌晨还在写代码就是凌晨爬起来写代码。深夜之所以工作效率高是因为不易分心,额!其实仔细想想晚上和白天并无多大区别...教程以Unity引擎为环境 ,重点放在Cg语言的学习和经典光照的计算上。为了突破难点,作者铺助了大量图文课件蛮牛酱导读:本文主要说的是2D的无缝自动拼接。这篇文章主要介绍一些卡通渲染的方法。包括:一个最常见的包含了卡通风格的漫反射+高光的场景。基于色调的卡通渲染。一种风格化的卡通高光的计算方法。unitymanual游戏蛮牛 ---
中国最大的手机游戏开发者技术社区! 热门文章最新文章unitymanual游戏蛮牛 ---
中国最大的手机游戏开发者技术社区!

我要回帖

更多关于 c attribute 的文章

 

随机推荐