借助Atrribute扩展UnityEdior

借助Atrribute扩展UnityEdior

image-20241231141303804

C# Attribute 简介

Attribute 是 C# 提供的一种强大的元数据机制,可以用来为代码的程序元素(如类、方法、属性等)附加额外的信息。这些附加信息可以在运行时通过反射机制读取,从而影响程序的行为。


Attribute 的特性

  1. 轻量级

    Attribute 不会直接影响代码运行,只是附加额外信息。

  2. 可扩展

    开发者可以创建自定义 Attribute。

  3. 强大

    常用于代码标记、配置、工具生成、验证等场景。


Attribute 的应用范围

可以应用到以下程序元素:

  • 类、结构、枚举
  • 方法、构造函数
  • 属性、字段
  • 接口、委托
  • 参数、返回值

预定义的 Attribute 示例

C# 提供了许多内置 Attribute,例如:

  1. [Obsolete]

    • 标记某个成员为已过时。
    [Obsolete("This method is deprecated. Use NewMethod instead.")]
    public void OldMethod() { }
    
  2. [Serializable]

    • 标记类可以序列化。
    [Serializable]
    public class MyClass { }
    
  3. [DllImport]

    • 用于调用非托管代码。
    [DllImport("user32.dll")]
    public static extern int MessageBox(int hWnd, string text, string caption, uint type);
    
  4. [Test]

    • 单元测试框架中常用的 Attribute(例如 NUnit 或 MSTest)。
    [Test]
    public void MyTestMethod() { }
    

自定义 Attribute

创建自定义 Attribute

  1. 定义一个继承自 System.Attribute 的类。
  2. 使用 AttributeUsage 控制 Attribute 的适用范围和行为。
[System.AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
public class MyCustomAttribute : Attribute
{public string Description { get; }public MyCustomAttribute(string description){Description = description;}
}

使用自定义 Attribute

[MyCustomAttribute("This is a sample class.")]
public class SampleClass
{[MyCustomAttribute("This is a sample method.")]public void SampleMethod() { }
}

读取自定义 Attribute

通过反射读取附加的 Attribute 信息:

var type = typeof(SampleClass);
var attributes = type.GetCustomAttributes(typeof(MyCustomAttribute), false);foreach (MyCustomAttribute attr in attributes)
{Console.WriteLine($"Description: {attr.Description}");
}

AttributeUsage 属性

AttributeUsage 是用来定义自定义 Attribute 的使用规则的 Attribute。

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, // 应用范围AllowMultiple = true,                             // 是否允许多次使用Inherited = true)]                                // 是否能被继承
public class MyCustomAttribute : Attribute
{// 定义逻辑
}

常见场景

  1. 标记元数据
    • 使用 Attribute 附加描述信息,例如文档注释、开发工具的自动生成代码标记。
  2. 代码验证
    • 结合反射读取 Attribute,用于校验输入数据。
  3. 控制序列化
    • 通过 Attribute 标记需要序列化的字段或属性,例如 JSON 序列化。
  4. 单元测试
    • 框架(如 NUnit、MSTest)通过 Attribute 标记测试方法。
  5. 绑定 UI 或框架
    • 框架(如 Unity、ASP.NET)通过 Attribute 简化绑定,例如 UnityEngine.SerializeField

优点与注意事项

优点:

  • 清晰地描述额外信息。
  • 可扩展性强,便于元编程。
  • 通过反射可以动态控制代码行为。

注意事项:

  1. 性能

    Attribute 的过多使用可能影响性能,尤其是需要频繁反射时。

  2. 复杂性

    需要熟悉反射机制才能正确使用 Attribute。

  3. 局限性

    Attribute 不支持运行时动态修改。


示例:Unity编辑器窗口获取文件路径

#if UNITY_EDITOR
using UnityEditor;
#endif
using System;
using UnityEngine;/// <summary>
/// Custom attribute to allow path selection in the Unity editor.
/// </summary>
public class PathSelectAttribute : PropertyAttribute
{public string Title { get; private set; }public string Extension { get; private set; }public PathSelectAttribute(string title = "Select File", string extension = "*"){Title = title;Extension = extension;}
}#if UNITY_EDITOR
[CustomPropertyDrawer(typeof(PathSelectAttribute))]
public class PathSelectDrawer : PropertyDrawer
{private string _lastSelectedPath = "";public override void OnGUI(Rect position, SerializedProperty property, GUIContent label){if (property.propertyType != SerializedPropertyType.String){EditorGUI.LabelField(position, label.text, "Use PathSelect with string.");return;}PathSelectAttribute pathAttribute = (PathSelectAttribute)attribute;EditorGUI.BeginProperty(position, label, property);// Display the current string fieldRect textFieldPosition = new Rect(position.x, position.y, position.width - 80, position.height);if(!string.IsNullOrEmpty(_lastSelectedPath))property.stringValue= _lastSelectedPath;property.stringValue = EditorGUI.TextField(textFieldPosition, label, property.stringValue);// Create the "Browse" buttonRect buttonPosition = new Rect(position.x + position.width - 75, position.y, 75, position.height);if (GUI.Button(buttonPosition, "Browse")){// Open file panelstring path = EditorUtility.OpenFilePanel(pathAttribute.Title, "", pathAttribute.Extension);if (!string.IsNullOrEmpty(path)){//使用变量保存选择的路径,避免在GUI循环中修改属性值_lastSelectedPath = path;}else{_lastSelectedPath= String.Empty;}//类似打开窗口类型任务终止GUI循环时调用GUIUtility.ExitGUI();}EditorGUI.EndProperty();}
}#endif//------测试-------
/// <summary>
/// Example usage of PathSelectAttribute.
/// </summary>
public class PathSelectExample : MonoBehaviour
{[PathSelect("Select a JSON file", "json")]public string filePath;
}

image-20241231141318895

总结

C# 的 Attribute 提供了一种灵活的元数据管理机制,广泛应用于框架、工具和自定义开发场景中。无论是使用预定义 Attribute,还是创建自己的 Attribute,都能极大提高代码的可读性和可扩展性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/863358.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C#实现LALR(1)解析器的生成器

Yet Another Compiler 参考lex和yacc的输入格式,参考虎书《现代编译原理-C语言描述》的算法,大力整合优化,实现了LALR(1)的C#生成器(暂命名为bitParser)。 词法分析器根据DFA和最小化DFA分别生成词法分析器代码(状态转换表、保留字、Token类型等)支持全Unicode字符。支持…

【新兴产业】量子信息

产业链 量子信息主要包括量子计算、量子通信和量子测量三大领域,在提升计算困难问题运算处理能力、加强信息安全保护能力、提高传感测量精度等方面,具备超越经典信息技术的潜力。 量子信息产业链从上游到下游主要包含基础光电元器件、量子通信 核心元器件、量子通信传输干线、…

【新兴产业】元宇宙

产业链 •顶层设计:政府从宏观角度为元宇宙的发展做出顶层设计,尤其在金融交易体系、社会治理制度方面给出明确定调和指明方向。 • 市场培育:地方政府因地制宜制定符合当地产业特色的元宇宙发展规划,并出台产业扶持政策、落地措施,制定未来执行计划。 • 产业联盟:建立与…

回首2024,展望2025,新年新“鲸”象~

回首 2024 年,数字孪生领域蓬勃发展,技术创新层出不穷,应用场景不断拓展。在这充满机遇与挑战的一年里,山海鲸可视化凭借国产自研的零代码数字孪生平台,为众多企业和政府机构提供了一站式的数字化解决方案,助力各行各业在数字化转型的道路上稳步前行。 1. 回首2024年 (一…

CICD Day2、基于jenkins Gitlab 的CICD web-demo配置

1、 代码提交 1.1 在服务器上创建一个web-demo的目录,用户web前端项目的开发目录 mkdir web-demo # 在web-demo目录下 编辑一个index.html的文件 cat index.html <!DOCTYPE html> <html> <head><meta charset="utf-8"><title>实例<…

CPU-Z处理器检测工具 v2.13.0中文绿色单文件

点击上方蓝字关注我 前言 CPU-Z是一个非常厉害的CPU检测小帮手。它能识别很多种类的CPU,而且打开和检测的速度都很快。这个工具能清楚地告诉我们关于CPU、主板、内存、显卡等硬件的详细信息,比如是哪个厂家生产的、处理器的名字、是怎么做出来的、封装技术怎么样,还有它们的…

uniapp(Hbuilderx)

目录微信开发者工具下载新建项目运行 微信开发者工具下载新建项目注意点 如果要打包安卓,需要勾上:运行微信小程序 1: 找到.exe路径,粘贴进去2:打开微信小程序“服务端口”

商品个性化推荐

商品个性化推荐 任务要求:二.原理讲解: 本项目的基于 用户的购买历史 和 商品之间的相似性 进行商品推荐。它主要包括两个核心部分:用户-商品矩阵 和 商品相似度计算。下面我会结合算法的原理和实际示例为你讲解这个推荐系统的工作原理。 2.1用户-商品矩阵(User-Product M…

探索新路径:金融行业如何借助内部知识库实现智能转型

引言 在数字化转型的浪潮中,金融行业正经历着前所未有的变革。随着大数据、人工智能等技术的飞速发展,金融机构不仅需要提升服务效率,更要优化内部管理,以创新驱动业务增长。内部知识库作为信息管理与知识分享的核心平台,正逐渐成为金融行业智能转型的关键驱动力。本文将探…

Listary 6.3.1.85 Windows文件管理:高效文件管理工具

点击上方蓝字关注我 前言 Listary是一个非常实用的Windows文件管理小帮手,它能让找文件和管理文件变得更快更容易。用了它,你可以更快地搜索到想要的文件或程序,还能通过一些快捷操作快速到达文件所在的位置。更重要的是,Listary能和Windows自带的文件管理器以及其他常用的…

断点输出大法快速定位编程错误

断点&输出大法快速定位编程错误 1、断点法 点红框位置就可以加每行代码的断点 再按F5进行debug断点&输出大法快速定位编程错误 1、断点法 点红框位置就可以加每行代码的断点再按F5进行debug操作,在下面的窗口看各函数的值 这种方法经常用在循环出现问题时进行处理 举个…

Nginx的referer参数的用法和原理

​ Nginx的referer参数是用于控制HTTP请求中的Referer字段的相关配置。这个参数的主要作用是限制或允许特定来源网站的访问,以加强安全性或控制流量。 用法:限制特定来源网站的访问: 可以使用referer参数来配置Nginx,使其只允许来自指定来源网站的请求。这有助于防止盗链或…