当前位置: 首页 > news >正文

C#中用于控制自定义特性(Attribute)

我们来详细解释一下 [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)] 这个 C# 属性。
在 C# 中,Attribute(特性)是一种用于向程序元素(如类、方法、属性等)添加元数据的机制。AttributeUsage 是一个特殊的、用于定义其他自定义特性如何被使用的元特性。
让我们分解 [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]

  1. [AttributeUsage(...)]:
    • 这是一个元特性,它被应用到一个自定义特性的定义上。
    • 它的作用是告诉编译器和开发人员,这个自定义特性应该如何被使用,以及有哪些限制。
  2. AttributeTargets.Class:
    • 这是 AttributeUsage 构造函数的第一个参数,类型是 AttributeTargets
    • AttributeTargets 是一个枚举类型,它定义了一系列的值,代表程序中的不同元素类型,例如类、结构、方法、属性、字段等。
    • AttributeTargets.Class 指定了这个自定义特性只能被应用在上。
    • 如果你想让特性可以应用在多个类型上,可以使用按位或运算符 | 来组合,例如 AttributeTargets.Class | AttributeTargets.Struct 表示可以应用在类或结构上。
  3. AllowMultiple = false:
    • 这是 AttributeUsage 构造函数的第二个参数(或者通过属性名称指定)。
    • 它是一个布尔值,控制是否允许同一个目标元素上应用多个相同类型的自定义特性。
    • false 表示不允许。一个类上只能有一个这种类型的特性。
    • true 表示允许。一个类上可以有多个这种类型的特性(例如,一个方法可以有多个 [Obsolete] 特性,每个特性可以带有不同的消息)。
  4. Inherited = false:
    • 这是 AttributeUsage 构造函数的第三个参数(或者通过属性名称指定)。
    • 它是一个布尔值,控制这个自定义特性是否会被继承
    • false 表示不继承。如果这个特性被应用在一个基类上,那么派生类不会自动拥有这个特性。
    • true 表示继承。如果这个特性被应用在一个基类上,那么派生类自动继承这个特性(默认值就是 true)。
      总结表格
      表格

举例说明
假设我们定义一个自定义特性 [DeveloperInfo],用于标记类的开发者信息,并且我们希望:

  1. 这个特性只能用在类上。
  2. 一个类上只能有一个 [DeveloperInfo] 特性。
  3. 这个特性不会被派生类继承。
    那么我们可以这样定义它:
// 定义自定义特性 DeveloperInfo
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
public class DeveloperInfoAttribute : Attribute
{public string Name { get; }public string Date { get; }public DeveloperInfoAttribute(string name, string date){Name = name;Date = date;}
}

现在,我们使用这个特性:

// 应用特性
[DeveloperInfo("张三", "2023-10-27")]
public class MyImportantClass
{// 类的实现public void DoSomething() { }
}
// 尝试在同一个类上应用第二个 DeveloperInfo 特性 - 编译错误!
// [DeveloperInfo("李四", "2023-10-28")] // 因为 AllowMultiple = false
// public class AnotherClass { } // 这行代码本身没问题,但上面这行会出错
// 尝试在方法上应用 - 编译错误!
// [DeveloperInfo("王五", "2023-10-29")]
// public void SomeMethod() { } // 因为 AttributeTargets 只指定了 Class
// 派生类不会继承基类的 DeveloperInfo 特性
public class DerivedClass : MyImportantClass
{// 这个类上没有 DeveloperInfo 特性,即使基类 MyImportantClass 有public void DoAnotherThing() { }
}

另一个例子:允许重复且可继承的特性
假设我们定义一个 [Tag] 特性,用于给类打标签,一个类可以有多个标签,并且这些标签会被派生类继承。

[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
public class TagAttribute : Attribute
{public string TagName { get; }public TagAttribute(string tagName){TagName = tagName;}
}
// 应用特性
[Tag("Utility")]
[Tag("Helper")]
[Tag("Core")]
public class UtilityClass
{// ...
}
// 派生类会继承基类的 Tag 特性
public class AdvancedUtilityClass : UtilityClass
{// 这个类自动拥有了 "Utility", "Helper", "Core" 三个标签// 也可以添加自己的标签[Tag("Advanced")]// ...
}

通过 AttributeUsage,你可以精确控制自定义特性的使用范围和行为,使其更符合设计意图。

http://www.xdnf.cn/news/954073.html

相关文章:

  • 【Dify】基于 Agent 实现热门新闻生成助手
  • 【教程】矩形重叠检测 -- 分离轴定理的应用
  • Vue 插槽(Slot)用法详解
  • UFW防火墙安全指南
  • 【算法-BFS实现FloodFill算法】使用BFS实现FloodFill算法:高效识别连通块并进行图像填充
  • 时间复杂度和算法选择
  • WinUI3开发_使用mica效果
  • vitepress添加图片放大功能
  • 基于2.4G功能的使用
  • encodeURIComponent和decodeURIComponent
  • 21-Oracle 23 ai-Automatic SQL Plan Management(SPM)
  • 多元隐函数 偏导公式法 (显示变化 + 隐式变化)
  • ABAP设计模式之---“Tell, Don’t Ask原则”
  • STL 1 容器
  • 基于生态系统服务(InVEST模型)的人类活动、重大工程生态成效评估、论文写作
  • 12.找到字符串中所有字母异位词
  • Oracle查询表空间大小
  • vue的<router-link>的to里面的query和params的区别
  • pocketflow库实现guardrail
  • Nginx server_name 配置说明
  • Qt插件化编程的全面解析(QPluginLoader)
  • 微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据
  • 云防火墙(安全组)配置指南:从入门到精通端口开放 (2025)
  • OCR、图像分类与目标检测
  • 雷达RCS计算中的旋转矩阵
  • 在Ubuntu上利用loongarch64交叉编译工具编译opencv4.4.0
  • 【排错】ollama报错unable to load model
  • 【知识点】第8章:程序设计方法论
  • CKA考试知识点分享(6)---PriorityClass
  • 自动化测试工具playwright中文文档-------19.评估JavaScript