从Unity中的Attribute到AOP(一)
首先来看一下微软官方对Attributes(C#)的定义:
https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/attributes/index
Attributes provide a powerful method of associating metadata, or declarative information, with code (assemblies, types, methods, properties, and so forth). After an attribute is associated with a program entity, the attribute can be queried at run time by using a technique called reflection. For more information, see Reflection (C#).
Attributes have the following properties:
Attributes add metadata to your program. Metadata is information about the types defined in a program. All .NET assemblies contain a specified set of metadata that describes the types and type members defined in the assembly. You can add custom attributes to specify any additional information that is required. For more information, see, Creating Custom Attributes (C#).
You can apply one or more attributes to entire assemblies, modules, or smaller program elements such as classes and properties.
Attributes can accept arguments in the same way as methods and properties.
Your program can examine its own metadata or the metadata in other programs by using reflection. For more information, see Accessing Attributes by Using Reflection (C#).
这段英文很简单,我们可以Get到如下几个点:
1,Attributes可以向你的程序中添加元数据。元数据是指你在程序中定义的类型的信息,所有的.net程序集都包含了一组描述定义类型以及类型成员的元数据。
2,可以添加一到多个Attribute到程序集,模块或者类。
3,Attributes可以接受参数。
4,程序可以利用反射来检查自己的元数据。
我们先抛开反射,看Attributes的定义,感觉Attributes像是在描述一个类:可以添加成员变量,可以写入元数据,可以接受参数。
而当我们使用的时候,需要这样写:
[DllImportAttribute("xxx,dll")]
或者这样
[DllImport("xxx.dll")]
注意,这里都没有分号。如果你还有特殊需求的话,可以写上可选参数,比如:
[DllImport("xxx.dll", ExactSpelling=false, SetLastError=false)]
我们可以看到这里语法有些怪异,首先是方括弧的使用,其次是函数参数的赋值上,如果我们需要写入赋值的参数名,往往会这么写:ExactSpelling : false。最后当我们使用Attributes的时候, 它附着的地方也很奇怪,看上去不像是类或者方法的一部门,但却能对类或者方法产生影响。
下面我们写一个系统自带的Attributes的范例:
假设我们有一个日志系统,分布在代码各处,主要分为3大类:网络日志(输出网络回调的各种状态),游戏内逻辑日志(用于调试信息),引擎底层日志(比如我们重写了UGUI)。日志的等级分为低等级,普通,紧急三种状态。
我们使用同一个日志管理系统来输出对应的日志。现在我希望能够过滤固定类型的日志,并且每次更改过滤条件的时候尽可能少地改动代码。这个案例在这里可能并不恰当,过滤日志的话还有很多更好更快的代码,这里仅做参考。
public class ToolKit
{
/// <summary>
/// 网络日志
/// </summary>
[Conditional("Network")]
[Conditional("Low")]
public static void LogNetworkLow()
{
Console.WriteLine("LogNetworkLow");
} [Conditional("Network")]
[Conditional("Normal")]
public static void LogNetworkNormal()
{
Console.WriteLine("LogNetworkNormal");
} [Conditional("Network")]
[Conditional("Urgent")]
public static void LogNetworkUrgent()
{
Console.WriteLine("LogNetworkUrgent");
} /// <summary>
/// 逻辑日志
/// </summary>
[Conditional("Logic")]
[Conditional("Low")]
public static void LogLogicLow()
{
Console.WriteLine("LogLogicLow");
} [Conditional("Logic")]
[Conditional("Normal")]
public static void LogLogicNormal()
{
Console.WriteLine("LogLogicNormal");
} [Conditional("Logic")]
[Conditional("Urgent")]
public static void LogLogicUrgent()
{
Console.WriteLine("LogLogicUrgent");
} /// <summary>
/// 引擎日志
/// </summary>
[Conditional("Engine")]
[Conditional("Low")]
public static void LogEngineLow()
{
Console.WriteLine("LogEngineLow");
} [Conditional("Engine")]
[Conditional("Normal")]
public static void LogEngineNormal()
{
Console.WriteLine("LogEngineNormal");
} [Conditional("Engine")]
[Conditional("Urgent")]
public static void LogEngineUrgent()
{
Console.WriteLine("LogEngineUrgent");
}
}
首先我们定义了一个ToolKit的类,里面有诺干静态函数,每个静态函数负责输出特定的日志(请无视这垃圾代码)。在每个函数上面,我们加了类似条件的东西。Conditional是系统定义的一个Attribute,作用是过滤条件。这段代码很好看懂,只是语法让人觉得有点诡异。
接着我们在主程序中,把所有输出都打印一遍。
static void Main(string[] args)
{
ToolKit.LogNetworkLow();
ToolKit.LogNetworkNormal();
ToolKit.LogNetworkUrgent(); ToolKit.LogLogicLow();
ToolKit.LogLogicNormal();
ToolKit.LogLogicUrgent(); ToolKit.LogEngineLow();
ToolKit.LogEngineNormal();
ToolKit.LogEngineUrgent(); Console.ReadKey();
}
执行程序,然而什么输出也没有。这说明我们设置的条件生效了。接下来我们在CS文件头上加入#define Normal。

似乎和我们的预期相同。把#define Normal改为#define Logic,再次运行。

完美。现在我想输出低等级的网络日志,在原来的#define Logic下面再加入一行#define Low,然后运行。

Oops,条件筛选似乎用了或而没用与。这里是一个需要注意的点,如果一定要用与条件筛选的话,可以用#if语句做条件判定,这里不再赘述了。
至此,我们对Attributes的使用有了一个初步的认识。下一讲,我们将对Attributes的原理进行剖析。
从Unity中的Attribute到AOP(一)的更多相关文章
- 从Unity中的Attribute到AOP(七)
本章我们将依然讲解Unity中的Attribute,继续命名空间在UnityEngine里的. PropertyAttribute,这个特性主要来控制变量或者类在Inspector里面的显示方式.和P ...
- 从Unity中的Attribute到AOP(五)
今天主要来讲一下Unity中带Menu的Attribute. 首先是AddComponentMenu.这是UnityEngine命名空间下的一个Attribute. 按照官方文档的说法,会在Compo ...
- 从Unity中的Attribute到AOP(四)
本篇我们将逐一讲解Unity中经常使用的Attribute(Unity对应的文档版本为2018.1b). 首先是Serializable,SerializeField以及NonSerialized,H ...
- 从Unity中的Attribute到AOP(三)
上一篇我们对系统的Attributes进行了MSIL代码的查看,了解到了其本质就是一个类的构造函数.本章我们将编写自己的Attributes. 首先我们定义书的属性代码,如下: [AttributeU ...
- 从Unity中的Attribute到AOP(六)
本文将重点对Unity剩下常用的Attribute进行讲解,其他不常用的Attribute各位可以自行去官方文档查阅. 首先是UnityEngine命名空间下的. ColorUsage,这个主要作用于 ...
- 从Unity中的Attribute到AOP(八)
本文将讲一下在UnityEditor命名空间下的一些特性. CallBackOrder,这个Attribute是所有带callback index的Attribute的基类,由于官方也没有给出详细的说 ...
- 从Unity中的Attribute到AOP(二)
上一篇文章我们初步了解了一下Attributes的含义,并且使用系统自带的Attributes写了点代码.在进一步解剖我们的代码之前,我觉得有个概念可能需要巩固一下:什么是元数据? 我们知道C#代码会 ...
- Unity中使用Attribute
Attribute是c#的语言特性 msdn说明如下: The Attribute class associates predefined system information or user-def ...
- Unity应用架构设计(12)——AOP思想的实践
想象一下,当程序所有的业务逻辑都完成的时候,你可能还来不及喘口气,紧张的测试即将来临.你的Boss告诉你,虽然程序没问题,但某些方法为什么执行这么慢,性能堪忧.领会了Boss的意图之后,漫长的排查问题 ...
随机推荐
- 基于ASP.MVC票据FormsAuthenticationTicket身份认证
做一个最基础的业务需求用户登录,将此用户的身份发回到客户端的Cookie,之后此用户再访问这个web应用就会连同这个身份Cookie一起发送到服务端.服务端上的授权设置就可以根据不同目录对不同用户的访 ...
- 跨平台应用集成(在ASP.NET Core MVC 应用程序中集成 Microsoft Graph)
作者:陈希章 发表于 2017年6月25日 谈一谈.NET 的跨平台 终于要写到这一篇了.跨平台的支持可以说是 Office 365 平台在设计伊始就考虑的目标.我在前面的文章已经提到过了,Micro ...
- log4j配置文件详解(转)
Log4J的配置文件(Configuration File)就是用来设置记录器的级别.存放器和布局的,它可接key=value格式的设置或xml格式的设置信息.通过配置,可以创建出Log4J的运行环境 ...
- 自学Zabbix3.8.1.1-可视化Visualisation-Graphs简单图表
自学Zabbix3.8.1.1-可视化Visualisation-Graphs简单图表 Zabbix提供了一些简单的图表,用于可视化由项目收集的数据. 用户不需要进行配置工作来查看简单的图表.他们是由 ...
- 自学Zabbix3.7-事件Event
配置item.trigger.都是为发送报警做准备的,什么是事件通知呢?简单的说故障发生了,zabbix会发邮件或者短信给你,告诉你服务器的一些状况. 1. 通知条件 发送通知,需要有如下步骤 定义一 ...
- web项目错误页面友好处理404,500等
写在前面: 在web项目中,可能会出现404.500等错误页面,给用户体验不怎么好,所以我们可以对这些错误页面进行友好的处理. 步骤: 1.配置web.xml: <!-- 错误页面友好显示 -- ...
- ios 去掉字符串中的空格 和指定的字符
[问题分析] .使用NSString中的stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]方法只是去掉左右 ...
- jsp程序设计:jstl之JSTL标签库
转载自:http://www.blogjava.net/haizhige/archive/2008/10/26/236783.html,个人进行了一些修改. 前言:写一个taglib一般可以继承Sim ...
- 通过 JS 判断页面是否有滚动条的简单方法
前言 最近在写插件的过程中,需要使用 JS 判断是否有滚动条,搜了一下,大致方法都差不多,但都有些啰嗦,代码不够简洁.最终通过参考不同方法,写了一个比较简单的方法.在判断滚动条的同时也需要计算滚动条的 ...
- ITS简要分析流程(using Qiime)
Qiime安装 参考资料:http://blog.sina.com.cn/s/blog_83f77c940101h2rp.html Qiime script官方说明http://qiime.org/s ...