c#笔记-特性

news2024/11/26 20:40:12

特性

添加特性

特性是一种用于给代码添加额外信息的声明性标签。
在修饰的元素之前,用方括号声明特性。

[Obsolete("过时的类")]
public class MyClass1
{

}

需要声明多个特性时,可以使用多个方括号,也可以在一个方括号里使用逗号隔开。
使用无参构造器的特性可以省略圆括号。

[Serializable, Obsolete("过时的类")]
public class MyClass2
{

}

[Serializable][Obsolete("过时的类")]
public class MyClass3
{

}

特性成员赋值

特性只有一个声明,没有后续的执行语句。
要为特性的成员赋值,使用命名参数在构造器里直接指定

[Obsolete("过时的类",DiagnosticId ="GPT")]
public class MyClass4
{

}

预定义特性

特性可以通过反射获取。
而你的编译器一直在观察你的代码,可以直接和一些特性交互。
以下是一些预定义的特性,编译器会对他们做出响应。

已过时

Obsolete特性用于标记已经过时的代码元素,不建议使用。
它可以接受一个字符串参数,用于说明过时的原因和替代方案。
它还可以接受一个布尔值参数,用于指示是否将使用过时元素视为编译错误

class MyClass5
{
	[Obsolete("此方法已经过时。请使用NewMethod", false)]
	public void OldMethod()
	{ 
	}

	public void NewMethod()
	{ 
	}
}

获取调用者信息

Caller Info特性是一组预定义的特性,用于获取调用者的信息,如文件路径、行号、成员名等 。
它们可以应用于可选的方法参数,当方法被调用时,编译器会自动为这些参数赋值。
这些特性有助于提供更详细的诊断和跟踪信息,而不需要显式传递参数。

  • CallerFilePathAttribute:获取源文件的完整路径,包含文件名和扩展名。
  • CallerLineNumberAttribute:获取源文件中调用方法的语句所在的行号。
  • CallerMemberNameAttribute:获取调用方法的成员名,如方法名、属性名、事件名等。

例如,下面的代码定义了一个TraceMessage方法,它有三个可选的参数,分别使用了上述三个特性。
当这个方法被其他地方调用时,编译器会自动为这些参数赋值为调用者的信息。

using System;
using System.Runtime.CompilerServices;

public class Trace
{
    public static void TraceMessage(string message,
        [CallerFilePath] string filePath = "",
        [CallerLineNumber] int lineNumber = 0,
        [CallerMemberName] string memberName = "")
    {
        Console.WriteLine($"Message: {message}");
        Console.WriteLine($"File path: {filePath}");
        Console.WriteLine($"Line number: {lineNumber}");
        Console.WriteLine($"Member name: {memberName}");
    }
}

下面的代码演示了如何在不同的地方调用TraceMessage方法,并输出不同的调用者信息。

public class Program
{
    public static void Main()
    {
        Trace.TraceMessage("Hello from Main");
        Foo();
        var bar = new Bar();
        bar.Baz();
    }

    public static void Foo()
    {
        Trace.TraceMessage("Hello from Foo");
    }
}

public class Bar
{
    public void Baz()
    {
        Trace.TraceMessage("Hello from Baz");
    }
}

输出结果如下:

Message: Hello from Main
File path: C:\Users\user\source\repos\TraceDemo\Program.cs
Line number: 11
Member name: Main
Message: Hello from Foo
File path: C:\Users\user\source\repos\TraceDemo\Program.cs
Line number: 16
Member name: Foo
Message: Hello from Baz
File path: C:\Users\user\source\repos\TraceDemo\Program.cs
Line number: 26
Member name: Baz

语言格式

某些特殊的语言格式,比如json,xml,正则表达式,在VS中有特殊的提示和语法着色。
使用语言格式特性,作用于函数参数,可以在传入实参时激活这种提示。

void Json([StringSyntax(StringSyntaxAttribute.Json)] string json ) { } 
void Regex([StringSyntax(StringSyntaxAttribute.Regex)] string regex ) { }

在这里插入图片描述

外部方法

外部方法必须使用DllImport特性,且必须添加static extern修饰符
外部方法可以允许你使用已经编译好的dll文件里面的方法。

class Extern
{
	[DllImport("user32.dll", EntryPoint = "MessageBoxA")]
	public static extern int MessageBox(int hwnd, string msg, string caption, int type);
}
Extern.MessageBox(0, "你调用了windos自带的dll,并弹出了一个窗口", "一个窗口",  0);

自定义特性

特性是一种继承自Attribute类的类,它可以具有类的所有功能,
但是通常用于给其他代码元素(如类、方法、属性等)添加一些额外的信息或行为。

class TipsAttribute : Attribute
{
	public string Tips;
}

可赋值成员

特性类中可以定义一些公共的字段或属性,用于存储特性的数据或配置。
这些成员可以在应用特性时,使用命名参数的语法进行赋值。
但是,只能使用常量表达式作为赋值的源,不能使用需要运行时计算或构造的值。

[Tips(Tips = "你好")]
class MyClass6
{

}

特性的构造过程

特性类和普通类一样,都需要通过构造函数来初始化。
不同的是,特性类的构造函数每次获取特性时都会被调用,而不是只在第一次获取时调用。
这意味着,如果特性类的构造函数中包含一些随机或不确定的逻辑,
那么多次获取同一个特性可能会得到不同的结果。

另外,一个特性类也是一个普通的类。
可以直接通过new来创建它的实例,而不一定要应用到某个代码元素上。

TipsAttribute tp = new TipsAttribute();
tp.Tips = "你好";

尽管没有这方面的限制,但是为了保持特性类的简洁和清晰,
建议只在特性类中定义一些常量或只读的成员。

特性的简易名字

一个特性类通常以Attribute结尾。但在应用特性时,可以省略结尾的Attribute
(只有应用特性时可以省略。其他情况下,如继承、声明、获取时都必须使用完整的名字)。

[Tips]
class MyClass7
{

}

如果要强调(或是在省略后有重名类)特性的名字就是原本这样,不是省略后的结果。
那么需要在前面加@

[@Tips2]
class Test { }


class Tips2Attribute : Attribute
{ 
	public string Tips; 
}
class Tips2  : Attribute
{
	public string Tips;
}

限制特性

你可以通过应用系统提供的AttributeUsageAttribute特性,
来指定你的特性类只能应用到某些代码元素上,
编译器会根据这个特性来检查你是否正确地使用了自定义特性。

[AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = true)]
class Tips3Attribute : Attribute
{
	public string Tips;
}

AttributeUsageAttribute构造函数接受一个枚举参数,表示可以应用自定义特性的目标类型。
可以使用位运算符来组合多个目标类型。

AllowMultiple属性表示是否允许同一个代码元素上有多个相同的自定义特性,默认是false
Inherited属性表示当有这个自定义特性的类被继承时,是否会将这个自定义特性传递给子类,默认是true

[Flags]
public enum AttributeTargets
{
    Assembly = 1, // 可以应用到程序集上
    Module = 2, // 可以应用到模块上,模块指的是可执行文件(.dll或.exe),而不是标准模块
    Class = 4, // 可以应用到类上
    Struct = 8, // 可以应用到结构体上,即值类型
    Enum = 16, // 可以应用到枚举上
    Constructor = 32, // 可以应用到构造函数上
    Method = 64, // 可以应用到方法上
    Property = 128, // 可以应用到属性上
    Field = 256, // 可以应用到字段上
    Event = 512, // 可以应用到事件上
    Interface = 1024, // 可以应用到接口上
    Parameter = 2048, // 可以应用到参数上
    Delegate = 4096, // 可以应用到委托上
    ReturnValue = 8192, // 可以应用到返回值上
    GenericParameter = 16384, // 可以应用到泛型参数上,目前只有C#、中间语言(MSIL)和发出的代码支持这个特性
    All = 32767 // 可以应用到任何代码元素上
}
// 应用到程序集上
[assembly: Tips3]

// 应用到模块上
[module: Tips3]

// 应用到类上,应用到泛型参数上
[Tips3]
public class Foo<[Tips3] T>
{
	// 应用到方法上,应用到返回值上,应用到参数上
	[Tips3] [return: Tips3]
	public int Plugh([Tips3] int x)
	{
		return 0;
	}

	// 应用到属性上
	[Tips3]
	public int Baz { get; set; }

	// 应用到字段上
	[Tips3]
	public string Qux;

	// 应用到事件上
	[Tips3]
	public event EventHandler Quux;

}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

STL好难(1):STL简介

目录 1. 什么是STL&#xff1a; 2. STL的版本&#xff1a; &#xff08;1&#xff09;原始版本 &#xff08;2&#xff09;P.J.版本 &#xff08;3&#xff09;RW版本 &#xff08;4&#xff09;SGL版本 3. STL的六大组件&#xff1a; 4. SLT的重要性 &#xff08;1&a…

医院医学影像系统PACS,使用手册和操作说明书。

首先&#xff0c;系统可实现检查预约、病人信息登记、计算机阅片、电子报告书写、胶片打印、数据备份等一系列满足影像科室日常工作的功能,并且由于影像数字化存储,用户可利用影像处理与测量技术辅助诊断、方便快捷地查找资料或利用网络将资料传输至临床科室&#xff0c;还可与…

femu使用记录

femu使用记录 环境搭建libnvme&#xff1a;libnvme.so.1: cannot open shared object file: No such file or directory调试方法 Briefly speaking, FEMU is a fast, accurate, scalable, and extensible NVMe SSD Emulator. Based upon QEMU/KVM, FEMU is exposed to Guest OS…

《花雕学AI》Poe 上的四种 AI 机器人,你该怎么选?ChatGPT、Sage、Claude 和 Dragonfly对比

虽然 ChatGPT 是一项革命性的技术&#xff0c;但它作为一个消费产品却有点失败。你可能会花很长时间等待 OpenAI 的聊天机器人加载&#xff0c;或者根本无法使用它&#xff0c;因为它太大了。就算你能用上它&#xff0c;它也很缓慢&#xff0c;而且它的界面也很丑陋。它甚至没有…

连接(基础版)

QUESTION ONE # Write your MySQL query statement below select unique_id,name from EmployeeUNI right join Employees on EmployeeUNI.id Employees.id 这题很显然有两张表需要进行连接&#xff0c;在我们确定完要取的字段后&#xff0c;就需要连接两张表&#xff0c;…

鸿蒙Hi3861学习十二-Huawei LiteOS-M(osXX与LOS_XX)

一、LOS_XX是什么 LOS_XX是LiteOS_M或LiteOS_A内核提供的接口。例如&#xff1a;LOS_TaskCreate、LOS_TaskCreate、LOS_SemCreate等。因为LiteOS_M和LiteOS_A是针对不同的内核&#xff0c;所以LOS_XX在实现上也是有所不同的。也就是说LOS_XX跟具体的内核类型是有关系的。 这里只…

伸展树详解

伸展树的概念 伸展树&#xff08;Splay Tree&#xff09;是仅依靠局部性原理和局部平衡分析&#xff0c;从而实现高效的自适应平衡树结构。是一种二叉查找树&#xff0c;其核心思想是将最近访问的节点旋转到根节点。每次进行访问、插入、删除等操作时&#xff0c;都会选择与之…

【云计算】Hadoop集群安装

文章目录 前言一、环境二、安装虚拟机及配置配置网络 三、安装Ubuntu及配置下载ISO镜像VMware安装UbuntuUbuntu配置&#xff1a;配置结果IP免密登录 JAVA安装hadoop安装&#xff1a;文件的作用core-site.xml&#xff1a;core-site.xmlyarn-site.xmlmapred-site.xml 修改配置&am…

【Linux网络】网络层IP和数据链路层

文章目录 1、网络层IP1.1 认识网络层1.2 IP报文格式和IP报文切片1.3 网段划分以及路由 2、数据链路层2.1 以太网帧格式2.2 ARP协议 3、其它重要协议或技术3.1 DNS技术3.2 ICMP协议3.3 NAT技术3.4 NAT和代理服务器 1、网络层IP 1.1 认识网络层 浅谈一下各层 应用层&#xff1a;…

JBoss 5.x/6.x 反序列化漏洞(CVE-2017-12149)复现

文章目录 一.前言二.影响版本三.环境搭建四.漏洞复现1.编写反弹shell的命令2.序列化数据生成3.发送POC 一.前言 该漏洞为 Java反序列化错误类型&#xff0c;存在于 Jboss 的 HttpInvoker 组件中的 ReadOnlyAccessFilter 过滤器中。该过滤器在没有进行任何安全检查的情况下尝试…

基于AT89C51单片机的温度计设计

点击链接获取Keil源码与Project Backups仿真图&#xff1a; https://download.csdn.net/download/qq_64505944/87773445 源码获取 主要内容&#xff1a; 设计一个简易温度计&#xff1b;要求电路实现如下功能&#xff1a; 设计通过单片机和数码管、led灯等组成&#xff0c;可…

巧用千寻位置GNSS软件| 一文学会曲线样

曲线放样是圆曲线形放样工具&#xff0c;在线路初堪、临时设计、临时放样采集坐标等作业过程中&#xff0c;曲线放样更加简单和方便。千寻位置GNSS软件提供了三种线型文件编辑放&#xff0c;分别是直线、圆曲线 和缓曲线。圆曲线说明:线型上任意一点的曲率、半径都相同;缓曲线说…

【剧前爆米花--爪哇岛寻宝】网络编程一些概念以及Java实现网络编程流程

作者&#xff1a;困了电视剧 专栏&#xff1a;《JavaEE初阶》 文章分布&#xff1a;这是一篇关于网络初识的文章&#xff0c;在这篇文章中剖析了网络编程的一些概念以及用Java实现网络编程的一些流程&#xff0c;希望对你有所帮助&#xff01; 目录 网络编程 含义和一些概念 …

sysMaster: 全新1号进程实现方案,秒级自愈,保障系统全天在线

认识 1 号进程和 sysMaster 在 Linux 操作系统中&#xff0c;1 号进程是 init 进程&#xff0c;它是所有其他进程的祖先进程。init 进程是系统启动时第一个被创建的进程&#xff0c;它负责启动和管理其他所有进程&#xff0c;并在系统关机时关闭它们。在现代 Linux 系统中&…

数组--part 4--长度最小的子数组(力扣299/904/76)

文章目录 算法基本思想leetcode 209 长度最小的子数组leetcode 904 水果成篮leetcode 76 最小覆盖子串 算法基本思想 首先对于滑动窗口&#xff0c;题目可以先去看看leetcode 209 进行相关的了解后&#xff0c;再来书写代码。 首先我们的第一想法肯定就是暴力解法&#xff1a…

html实现汉诺塔小游戏

文章目录 1.设计来源汉诺塔由来1.1 主界面1.2 游戏规则1.3 游戏完成界面 2.效果和源码2.1 动态效果2.2 源代码 源码下载 作者&#xff1a;xcLeigh 文章地址&#xff1a;https://blog.csdn.net/weixin_43151418/article/details/130606736 html实现汉诺塔小游戏源码 汉诺塔&…

数据结构-链表(详解)

前言&#xff1a;内容包括&#xff1a;链表的分类&#xff0c;无头单向非循环链表的增删查改的实现&#xff0c;带头双向循环链表的增删查改的实现 目录 链表的分类 1. 单向或者双向 ​编辑 2. 带头或者不带头 3. 循环或者非循环 无头单向非循环链表&#xff1a; ​编辑…

造梦日记 Printidea 用户手册

*Hi 造梦日记* 欢迎来到造梦日记的空间&#xff5e; 造梦日记Printidea是一款基于AI算法、输入文字或图片即可生成高质量图片的工具&#xff0c;由西湖大学深度学习实验室和西湖心辰联合出品&#xff0c;超强算力&#xff0c;0.8秒出图&#xff0c;目前支持微信小程序、网页端…

边缘计算盒子的特点?边缘计算盒子适用于什么场景

边缘计算盒子&#xff08;Edge Computing Box&#xff09;是一种用于边缘计算的硬件设备&#xff0c;它通常是一个小型的计算设备&#xff0c;具备一定的计算能力和存储资源&#xff0c;并且能够连接到网络。边缘计算盒子的主要目的是在物联网&#xff08;IoT&#xff09;和分布…

续ShaderEditor、Inspector之后又一成功爆品,2周260+单!

01 前言 大家好&#xff0c;我是98K&#xff01;五一前&#xff0c;我上架 Cocos Store 的『高性能割草框架』增加 Cocos Creator 2.4.x 引擎&#xff0c;已经支持的老铁可免费更新&#xff01; 后续的更新计划是&#xff1a;完善2D游戏案例、增加3D案例、支持RVO和群聚&#…