从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的意图之后,漫长的排查问题 ...
随机推荐
- Vue深度学习(3)
基础 Vue.js允许自定义指令,实质上是让你教 Vue一些新技巧:怎样将数据的变化映射到 DOM 的行为.可以使用 Vue.directive(id, definition) 的方法传入指令 id ...
- laravel会话驱动扩展—连接自定义会话管理系统
laravel 版本:5.3.* 用laravel开发公司信息系统过程中,由于业务或安全问题的考虑,会有一些特殊的用户会话管理方面的需求,如多个子系统会话统一管理或A系统业务操作导致B系统中某些在线用 ...
- MPSOC之9——host、embeded间tftp、nfs、ftp环境搭建
tftp 可传输单个文件,不能传文件夹 需要通过命令传输文件,略显复杂 ==一般调试kernel时,用uboot通过tftp方式启动,不用每次都烧写存储介质== nfs 在host linux(ubu ...
- python __getattr__ 巧妙应用
在之前的文章有提到__getattr__函数的作用: 如果属性查找(attribute lookup)在实例以及对应的类中(通过__dict__)失败, 那么会调用到类的__getattr__函数, ...
- <大话设计模式>笔记
读完了<大话设计模式>这本书,收获很多,对程序设计有了很多新的理解.将每章模式的大概要点做了些笔记以备查阅,一些设计模式书读完也对其了解得不是很透彻,需要以后在实践中来不断地加深理解吧.读 ...
- nova创建虚拟机源码系列分析之二 wsgi模型
openstack nova启动时首先通过命令行或者dashborad填写创建信息,然后通过restful api的方式调用openstack服务去创建虚拟机.数据信息从客户端到达openstack服 ...
- 使用CSS画图之三角形(一)
简单的画一个三角形,代码如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset ...
- Anti-pattern/反模式
常见的与"直觉"相背离的anti-pattern产生的实际原因是没有深入.全面地考虑问题,即只关注到自己关心的方面,忽略了其他重要的.起相反作用的因素. 所以这个"直 ...
- Linux_服务器_07_ 将用户设置为管理员
二.参考资料 1.CentOS普通用户获得管理员权限 2.linux下添加用户并赋予root权限
- css3特效样式库
直接调用样式类即可: /* animation */ .a-bounce,.a-flip,.a-flash,.a-shake,.a-swing,.a-wobble,.a-ring{-webkit-an ...