【C#学习笔记】【Attribute】

C#制作ORM映射学习笔记一 自定义Attribute类 之前在做unity项目时发现只能用odbc连接数据库,感觉非常的麻烦,因为之前做web开发的时候用惯了ORM映射,所以我想在unity中也用一下ORM(虽然我知道出于性能的考虑这样做事不好的,不过自己的小项目吗管他的,自己爽就行了)。不过现在世面上的ORM映射基本都是为web项目设计的,与unity项目很难契合,所以我决定自己做一个简易的ORM映射。虽然想的很美但是实际做起来才发现还是挺复杂的,所 阅读详情

C#学习笔记系列

第一章 【C#学习笔记】【StackTrace】
第二章 【C#学习笔记】【Attribute】



前言

学习特性的使用,包括对.Net自带的三种预定义特性:Obsolete、Conditional、AttributeUsag的详细讲解,也列举了常用的特性,其中包括控件设计时要用到的一系列特性,最后介绍了如何进行自定义特性(仅以枚举作为示例)。


一、Attribute介绍

Attribute(特性)
MSDN给出定义:
Attribute类将预定义的系统信息或用户定义的自定义信息与目标元素相关联。
目标元素可以是程序集、类、构造函数、委托、枚举、事件、字段、接口、方法、可移植可执行文件模块、参数、属性(Property)、返回值、结构或其他特性(Attribute)。

二、Obsolete

Obsolete是.Net自带的三种预定义特性之一,该特性可以用来声明程序体是过时的,一个程序在不断迭代更新的过程中,总会出现要用新方法代替老方法的情况,但又不能删除老方法因为旧的项目在用,这是我们使用这个特性就能起到提示作用,Obsolete特性将程序结构标注为被弃用的。
在这里插入图片描述Obsolete有三个重载

public sealed class ObsoleteAttribute : Attribute
{
    //表示该程序体是被弃用的
    public ObsoleteAttribute();
    //string参数可以输入提示内容,在鼠标移动到程序体名称上显示,默认为“已过时”
    public ObsoleteAttribute(string? message);
    //bool参数用来表示该弃用方法是否编译报警,若为true,被使用时,会产生编译器错误,无法编译成功;若为false,则只是编译警告,告知方法是弃用的,但仍可编译成功并运行
    public ObsoleteAttribute(string? message, bool error);
}

三、Conditional

Conditional是.Net自带的三种预定义特性之一,位于System.Diagnostics命名空间下,这个特定通过条件判断决定是否运行下面对应的程序体
在这里插入图片描述

可以看到,定义了“Debug”字符串,方法Test1会运行,未定义“Release”字符串,Test2不会被运行。

四、AttributeUsage

AttributeUsag是.Net自带的三种预定义特性之一,仅对继承自Attribute的派生类有效,目的是控制当前类的使用范围。
如下面代码,定义了一个AttributeUsage的自定义特性,在AttributeUsage参数中传入了AttributeTargets.Method,指定当前特性仅对方法有效。

[AttributeUsage(AttributeTargets.Method)]
public sealed class FlowDemoAttribute : Attribute
{
    public FlowDemoAttribute() { }

    public string? Name { get; set; }

    public string? GetDisplayName()
    {
        return Name;
    }
}

那么在使用这个特性的时候,就只能定义在方法的上面,若放到其他的机构如字段,就会报错,如下图所示
在这里插入图片描述在这里插入图片描述如果需要指定对多个程序体有效的话,这里写多个目标,中间用 | 隔开,或者指定AttributeUsage.All,表示对所有程序体有效

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)]

AttributeUsage有两个重载

public sealed class AttributeUsageAttribute: Attribute
{
    //AttributeTargets参数规定特性可被放置的语言元素。它是枚举器 AttributeTargets 的值的组合,默认为“AttributeUsage.All”
    public AttributeUsageAttribute(AttributeTargets validOn);
    //allowMultiple参数,如果为 true,则该特性是多用的。默认值是 false(单用的)
    //inherited参数,如果为 true,则该特性可被派生类继承。默认值是 false(不被继承)
    public AttributeUsageAttribute(AttributeTargets validOn, bool allowMultiple, bool inherited);
}

AttributeTargets是一个枚举,它包括以下内容:

namespace System
{
    //
    // 摘要:
    //     Specifies the application elements on which it is valid to apply an attribute.
    [Flags]
    public enum AttributeTargets
    {
        //
        // 摘要:
        //     Attribute can be applied to an assembly.
        Assembly = 1,
        //
        // 摘要:
        //     Attribute can be applied to a module. Module refers to a portable executable
        //     file (.dll or.exe) and not a Visual Basic standard module.
        Module = 2,
        //
        // 摘要:
        //     Attribute can be applied to a class.
        Class = 4,
        //
        // 摘要:
        //     Attribute can be applied to a structure; that is, a value type.
        Struct = 8,
        //
        // 摘要:
        //     Attribute can be applied to an enumeration.
        Enum = 16,
        //
        // 摘要:
        //     Attribute can be applied to a constructor.
        Constructor = 32,
        //
        // 摘要:
        //     Attribute can be applied to a method.
        Method = 64,
        //
        // 摘要:
        //     Attribute can be applied to a property.
        Property = 128,
        //
        // 摘要:
        //     Attribute can be applied to a field.
        Field = 256,
        //
        // 摘要:
        //     Attribute can be applied to an event.
        Event = 512,
        //
        // 摘要:
        //     Attribute can be applied to an interface.
        Interface = 1024,
        //
        // 摘要:
        //     Attribute can be applied to a parameter.
        Parameter = 2048,
        //
        // 摘要:
        //     Attribute can be applied to a delegate.
        Delegate = 4096,
        //
        // 摘要:
        //     Attribute can be applied to a return value.
        ReturnValue = 8192,
        //
        // 摘要:
        //     Attribute can be applied to a generic parameter. Currently, this attribute can
        //     be applied only in C#, Microsoft intermediate language (MSIL), and emitted code.
        GenericParameter = 16384,
        //
        // 摘要:
        //     Attribute can be applied to any application element.
        All = 32767
    }

五、常用的特性

在.Net系统库中有很多定义好的特性,接下来挑部分常用的特性做简单介绍

FlagsAttribute
作用域:Enum
说明:指示可以将枚举作为位域(一组标志)处理,即两个枚举可以进行与(&)或(|)运算(二进制形式),通过HasFlag()判断是否包含。
详细说明:
使用[Flags]的场景:枚举的类型是不唯一的,比如颜色,一张图片可能同时包含枚举中的几种颜色,通过EColorValue.HasFlag(EColor.yellow);判断是否包含,或者通过"|“”&"来作计算;
不使用[Flags]的场景:枚举的类型是唯一的,比如用户权限,要么是操作员,要么是管理员。

SerializableAttribute
作用域:Class,Struct,Rnum,Delegate
说明:指示一个类可以序列化。

ComVisibleAttribute
作用域:Assembly,Class,Struct,Enum,Method,Propery,Field,Interface,Delegate
说明:控制程序集中个别托管类型、成员或所有类型对COM的可访问性。

DisplayAttribute
作用域:Method,Property,Field,Parameter
说明:提供一个通用特性,使您可以为实体分部类的类型和成员指定可本地化的字符串。

控件设计中会用到的特性:

BrowsableAttribute
作用域:All
说明:指定一个属性或事件是否应显示在“属性”窗口中。
CategoryAttribute
作用域:All
说明:指定当属性或事件显示在一个设置为“按分类顺序”模式的System.Windows.Forms.PropertyGrid控件中,用于给属性或事件分组的类别的名称。
DescriptionAttribute
作用域:All
说明:指定属性或事件的说明。
BindableAttribute
作用域:All
说明:指定成员是否通常用于绑定。无法继承此类。
DefaultPropertyAttribute
作用域:Class
说明:指定组件的默认属性。
DefaultValueAttribute
作用域:All
说明:指定属性的默认值。
EditorAttribute
作用域:All
说明:指定用来更改属性的编辑器,无法继承此类。
LocalizableAttribute
作用域:All
说明:指定属性是否应本地化,无法继承此类。
DesignerSerializationVisibilityAttribute
作用域:Method,Property,Field,Event
说明:指定在设计时序列化组件上的属性时所使用的持久性类型。
TypeConverterAttribute
作用域:All
说明:指定用作此特性所绑定到的对象的转换器的类型,无法继承此类。
DefaultEventAttribute
作用域:Class
说明:指定组件的默认事件。

六、自定义特性

.Net 框架允许创建自定义特性,用于存储声明性的信息,且可在运行时被检索。该信息根据设计标准和应用程序需要,可与任何目标元素相关。

创建并使用自定义特性包含四个步骤:

  1. 声明自定义特性
  2. 构建自定义特性
  3. 在目标程序元素上应用自定义特性
  4. 通过反射访问特性

6.1. 声明自定义特性

一个新的自定义特性应派生自 System.Attribute 类,我们声明一个名为FlowCtrlAttribute的自定义特性:

[AttributeUsage(AttributeTargets.Field)]
public sealed class FlowCtrlAttribute : Attribute
{
    //TODO..
}

6.2. 构建自定义特性

让我们构建一个名为 FlowCtrlAttribute 的自定义特性,该特性将存储流程图中控件的类型名称、宽高大小信息。它存储下面的信息:

  • 流程图控件类型名称
  • 流程图控件默认宽度大小
  • 流程图控件默认高度大小

下面的代码演示了 FlowCtrlAttribute 类:

[AttributeUsage(AttributeTargets.Field)]
public sealed class FlowCtrlAttribute : Attribute
{
    /// <summary>
    /// 流程图控件类型名称
    /// </summary>
    public string? TypeName { get; set; }
    /// <summary>
    /// 流程图控件默认宽度大小
    /// </summary>
    public double Width { get; set; }
    /// <summary>
    /// 流程图控件默认高度大小
    /// </summary>
    public double Height { get; set; }

    public FlowCtrlAttribute() { }
    public FlowCtrlAttribute(string typeName, double width, double height)
    {
        this.TypeName = typeName;
        this.Width = width;
        this.Height = height;
    }

    public string? GetTypeName()
    {
        return TypeName;
    }
    public double GetWidth()
    {
        return Width;
    }
    public double GetHeight()
    {
        return Height;
    }
}

6.3. 在目标程序元素上应用自定义特性

通过把特性放置在紧接着它的目标之前,来应用该特性,我们这里应用于枚举的场景:

public enum EFlowControl
{
    [FlowCtrl(TypeName = "开始", Width = 80, Height = 30)]
    StartControl,
    [FlowCtrl(TypeName = "结束", Width = 80, Height = 30)]
    FinishControl,
    [FlowCtrl(TypeName = "行为", Width = 80, Height = 30)]
    ActionControl,
    [FlowCtrl(TypeName = "条件", Width = 80, Height = 60)]
    ConditionControl,
    [FlowCtrl(TypeName = "文件", Width = 80, Height = 40)]
    FileControl,
    [FlowCtrl(TypeName = "模块", Width = 80, Height = 40)]
    ModuleControl,
    [FlowCtrl(TypeName = "预设模块", Width = 100, Height = 40)]
    DefineModuleControl,
}

6.4. 通过反射访问特性

反射指程序可以访问、检测和修改它本身状态或行为的一种能力。

程序集包含模块,而模块包含类型,类型又包含成员。反射则提供了封装程序集、模块和类型的对象。

您可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。然后,可以调用类型的方法或访问其字段和属性。

优缺点
优点:

  • 反射提高了程序的灵活性和扩展性。
  • 降低耦合性,提高自适应能力。
  • 它允许程序创建和控制任何类的对象,无需提前硬编码目标类。

缺点:

  • 性能问题:使用反射基本上是一种解释操作,用于字段和方法接入时要远慢于直接代码。因此反射机制主要应用在对灵活性和拓展性要求很高的系统框架上,普通程序不建议使用。
  • 使用反射会模糊程序内部逻辑;程序员希望在源代码中看到程序的逻辑,反射却绕过了源代码的技术,因而会带来维护的问题,反射代码比相应的直接代码更复杂。

反射(Reflection)的用途
反射(Reflection)有下列用途:

  • 它允许在运行时查看特性(attribute)信息。
  • 它允许审查集合中的各种类型,以及实例化这些类型。
  • 它允许延迟绑定的方法和属性(property)。
  • 它允许在运行时创建新类型,然后使用这些类型执行一些任务。

通过反射获取枚举的特性中存储的数据:

public static class EumHelper
{
    /// <summary>
    /// 获得枚举的TypeName
    /// </summary>
    /// <param name="eum">枚举</param>
    /// <returns>TypeName</returns>
    public static string GetTypeName<T>(this Enum eum)
    {
        Type type = eum.GetType();//先获取这个枚举的类型
        FieldInfo? field = type.GetField(eum.ToString());//通过这个类型获取到值
        FlowCtrlAttribute? obj = (FlowCtrlAttribute?)field?.GetCustomAttribute(typeof(FlowCtrlAttribute));//得到特性
        return obj?.GetTypeName() ?? string.Empty;
    }

    /// <summary>
    /// 获得枚举的Width
    /// </summary>
    /// <param name="eum">枚举</param>
    /// <returns>Width</returns>
    public static double GetWidth(this Enum eum)
    {
        Type type = eum.GetType();//先获取这个枚举的类型
        FieldInfo? field = type.GetField(eum.ToString());//通过这个类型获取到值
        FlowCtrlAttribute? obj = (FlowCtrlAttribute?)field?.GetCustomAttribute(typeof(FlowCtrlAttribute));//得到特性
        return obj?.GetWidth() ?? double.NaN;
    }

    /// <summary>
    /// 获得枚举的Height
    /// </summary>
    /// <param name="eum">枚举</param>
    /// <returns>Height</returns>
    public static double GetHeight(this Enum eum)
    {
        Type type = eum.GetType();//先获取这个枚举的类型
        FieldInfo? field = type.GetField(eum.ToString());//通过这个类型获取到值
        FlowCtrlAttribute? obj = (FlowCtrlAttribute?)field?.GetCustomAttribute(typeof(FlowCtrlAttribute));//得到特性
        return obj?.GetHeight() ?? double.NaN;
    }
}

总结

不积硅步,何以致千里

Protege新手入门:5分钟搞定本体建模基础(附实战案例) 本文为Protege本体建模新手提供了一份快速入门指南。通过构建一个关于“披萨”的实战案例,详细讲解了从环境准备、定义核心类(Classes)、建立对象属性(Object Properties)到设置数据属性(Data Properties)和创建个体的完整流程。文章旨在帮助读者绕过复杂理论,在5分钟内直观掌握本体建模的基础操作,快速建立知识图谱构建的信心。 阅读详情

相关推荐

ubuntu安装英伟达显卡驱动后wifi消失解决方法

ubuntu安装英伟达显卡驱动后(比如4090和3090等),会把wifi和蓝牙驱动去除,导致wifi无法连接。需要重新下载驱动安装。

人工智能(AI)技术,大模型技术,深度学习,机器学习,计算机视觉,AI工具实践应用等分享 3903

.net----特性

Conditional特性通过测试条件编译符号来确定适用的条件采用一个或多个Conditional特性修饰条件特性类条件方法标记为条件方法的调用取决于是否定义了预处理符号("DEBUG")("DEBUG")("TRACE")通过直接或间接地从System.Attribute类派生创建特性类的声明遵循下列规则:派生类的类名一般采用XXXAttribute的命名规范,类名就是特性名构造函数的参数是自定义特性的定位参数。

醉卧考场君莫笑 699

ADS2019学习笔记:三、SPICE model导入

以BZX84-C33 SPICE model为例,学习如何在ADS2019中导入SPICE model。

qq_42945911的博客 6492

C# —— 特性

conditional:将一些函数隔离出来,相比来说特性歌里策略要比 #define不容易出错。[Conditional("URL")] // 当定义了URl执行f1方法。

一个新人博客,愿多多支持。 703

【SABRE 3D, SABRE 3DxT,LAM设备】2025年9月10日

前文:SABRE 3D系列机台简介本章节详细阐述了在维护期间锁定电气、机械、热力学及重力组件以及化学管线输入的锁定操作流程,旨在降低人员受伤风险。p42~p55。

weixin_46735260的博客 1612

从拧螺丝到精密装配:三菱伺服电机扭矩控制在工业自动化中的实战解析

本文深入解析三菱伺服电机扭矩控制在工业自动化中的实战应用,重点介绍MR-J4系列伺服系统的高精度扭矩响应技术。从螺丝紧固到精密装配,详细讲解扭矩控制模式的选择、硬件配置、参数设置及典型故障排查方案,帮助工程师提升生产效率和产品质量。

weixin_29186249的博客 470

ASP.NET 中 ObsoleteAttribute 属性的使用

 一、Obsolete属性使用方法 1、Obsolete attribute位于System命名空间,它是一个attribute类型,以Obsolete或者ObsoleteAttribute来指定,在编译时,会自动添加上 “Attribute” 后缀。 2、指定一个attribute,用方括号[]围起所期望的attribute,置于所要修饰的方法、接口、属性、委托、事件等

whaxrl的专栏 1181

zemax像差参数Ray Fan/Spot Diagram/MTF/....讲解三

zemax像差参数Ray Fan/Spot Diagram/MTF/....讲解三

weixin_72050316的博客 1384

反射和特性

标志的定义 1、标识符(类名、方法名等)是程序员写给自己或其他程序员看的 2、程序无法通过标识符知道其自身的含义 3、但是我们可以使用标志来标记标识符的含义,程序可以读取标志从而得知一个标识符的含义 4、标志就像一本字典给每个字做的注解 class ABC { public ABC(string s) { } } [ABC("这是标志")] ==> new ABC("这是标志") 反射的定义 反射:在程序运行时可以指导一个类有哪些成员,每个成员方法上有哪些标志、几个参数、每个参数的

ht_game的博客 197

栅极驱动电路设计(一)

SiC驱动电路设计需满足更高标准,重点包括:驱动电压需18~20V开通、-3~-5V关断;栅极电阻优选5~10Ω以平衡开关性能与可靠性;必须集成欠压保护(阈值11~15V)和快速短路保护。多电平驱动控制通过动态调节栅压和驱动强度优化性能,如前期弱驱动抑制振荡,后期强驱动降低损耗。以NCE120ED65VTP4为例,栅压从18V提升至20V可使导通损耗降低15%。相比传统方案,有源驱动(含数字分段和模拟闭环控制)能更灵活地提升开关速度与效率。

嵌入式老牛的博客 449

【嘉立创EDA】PCB金属包边设计快捷方法

本文使用嘉立创EDA,描述如何在PCB设计时,快速增加边框包边设计,特别是金属包边(伪)——这里标记(伪)是因为该这里的包边特指不含边缘壁。请参考本文时特别注意!本文将此过程记录,以供有需要的读者参考。

l64481000的博客 1733

.NET ObsoleteAttribute

对于有不同版本的程序代码,obsoleteattribute显得大有用武之地。如果开发了一个新的方法,并且可以确定不再希望使用某方法,那么就可以使用Obsoleteattribute来修饰该方法,编译代码后,按警告/错误提示信息逐一更正原来的代码。在一个大型工程中,有助于协调不同的程序员所采用的方法。 using System; using System.Collections.Generic;

tomcat的专栏 801

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

C# 中的 Attribute 学习笔记

Attribute的实例化 1. 不使用new操作符来产生实例,而是使用在方括号里调用构造函数的来产生实例。 2. 方括号必需紧挨着放置在被附着目标的前面。 3. 因为方括号里空间有限,不能像使用new那样先构造对象后再对对象的属性(Property)一一赋值。因此,对Attribute实例的属性的赋值也都挤在了构造函数的圆括号里 值得注意的是: 1. 构造函数的参数是一定要写...

dibiemian0810的博客 135

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

C#学习笔记 Attribute(特性)

简单地说,特性(Attribute)是与类、结构、方法等元素相关的额外信息,是对元信息的扩展。通过Attribute可以使程序、甚至语言本身的功能得到增强。 Attribute是C#中一种特有的语法成分,它可以作用于各种语言要素,如命名空间、类、方法、字段、属性、索引器,等等,都可以附加上一些特定的声明信息。Attribute与元数据一起存储于程序集中,编译器或者其他程序可以读取并利用这些信息。 ...

不导翁的博客 869

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

C#学习笔记--Attribute

直接或间接继承自System.Attribute的类是Attribute,按照约定,属性的名字应该带一个Attribute的后缀,当然不带也不会引起编译时的错误,只不过需要注意的是以下内容 usingSystem;[AttributeUsage(AttributeTargets.All)]publicclassXAttribute:Attribute{}[X]...

weixin_30596735的博客 126

C# 学习笔记(Attribute) - 07

AttributeIts not static fixed by the language it self, and youre free to invent an asscoiate any information of any kind.An attribute is actually a class derived from the System.Attribute.It

Make Good Stuff Happen~! 992

学习笔记--C#特性Attribute(一)

这个框框好烦人啊,删不掉 一、背景 [serializable] public class Person(){} 这是我第一次看到特性(Attribute),那时我还不知道这是什么,怎么会有这种写法,让我纠结了很久,我只知道,加了这个后,这个类就可以序列化了。 二、使用 ①定义自己的Attribute //自定义特性,跟普通的类差不多,继承Attr...

LYPPPP0000的博客 230

C#学习笔记 -- Attribute

学习参考: http://www.cnblogs.com/dudu/articles/4449.html http://www.cnblogs.com/anytao/archive/2007/04/19/must_net_03.html 今天在讨论IPC通信契约的时候,卢工提到使用Attribute来描述具体的接口方法的命令信息。发现对 Attribute的概念还不是很熟悉,因此对其...

weixin_30628077的博客 120

C#学习笔记(十六):Attribute

Attribute可以为类或方法添加一些附加的信息,我们可以看看MSDN对Attribute的描述: 公共语言运行时允许你添加类似关键字的描述声明,叫做attributes, 它对程序中的元素进行标注,如类型、字段、方法和属性等。Attributes和Microsoft .NET Framework文件的元数据保存在一起,可以用来向运行时描述你的代码,或者在程序运行的时候影响应用程序的行为。...

weixin_30810239的博客 83

转:C#制作ORM映射学习笔记一 自定义Attribute类

之前在做unity项目时发现只能用odbc连接数据库,感觉非常的麻烦,因为之前做web开发的时候用惯了ORM映射,所以我想在unity中也用一下ORM(虽然我知道出于性能的考虑这样做事不好的,不过自己的小项目吗管他的,自己爽就行了)。不过现在世面上的ORM映射基本都是为web项目设计的,与unity项目很难契合,所以我决定自己做一个简易的ORM映射。虽然想的很美但是实际做起来才发现还是挺复杂的,所...

cillent_boy的专栏 479

C#学习笔记之四(Attribute, Reflection, Thread, Thread Synchronization)

Atributes: //can add metadata in program, It store with the program //using ILDasm to check atributes   //usage [CodeReviewAttribute("08/08/2005", "Allan Zhang",  Comment = "That is a Attribute test")

1334

【C#笔记自用1】

ContextMenu] 和 [ContextMenuItem]:在Inspector面板的ContextMenu中添加自定义选项,允许开发者通过右键菜单快速执行某些操作或调用方法。[Header]:在Inspector面板中为字段组添加标题,有助于组织和管理大量字段。[Space]:在Inspector面板中的字段之间添加额外的间距,提高可读性。

weixin_45478456的博客 2038

C#学习笔记之四(Attribute, Reflection, Thread, Thread Syn

<!--google_ad_client = "pub-2947489232296736";/* 728x15, 创建于 08-4-23MSDN */google_ad_slot = "3624277373";google_ad_width = 728;google_ad_height = 15;//--><script type="text/javascript"

zgqtxwd的专栏 708
上一篇: WPF下实现控件的拖拽功能
下一篇: 【C#学习笔记】【Interface】
Aflashstar
博客等级 码龄12年 205粉丝 38原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值