.NET 的反射机制简单介绍

 

1、什么是反射 

  Reflection,中文翻译为反射。  这是.Net中获取运行时类型信息的方式,.Net的应用程序由几个部分:

‘程序集(Assembly)’、‘模块(Module)’、‘类型(class)’组成,而反射提供一种编程的方式,让程序员可以在程序运行期获得这几个组成部分的相关信息,例如:

  Assembly类可以获得正在运行的装配件信息,也可以动态的加载装配件,以及在装配件中查找类型信息,并创建该类型的实例。  Type类可以获得对象的类型信息,此信息包含对象的所有要素:方法、构造器、属性等等,通过Type类可以得到这些要素的信息,并且调用之。  MethodInfo包含方法的信息,通过这个类可以得到方法的名称、参数、返回值等,并且可以调用之。  诸如此类,还有FieldInfo、EventInfo等等,这些类都包含在System.Reflection命名空间下。

 

2、命名空间与装配件的关系 

  很多人对这个概念可能还是很不清晰,对于合格的.Net程序员,有必要对这点进行澄清。  命名空间类似与Java的包,但又不完全等同,因为Java的包必须按照目录结构来放置,命名空间则不需要。

  装配件是.Net应用程序执行的最小单位,是编译出来的.dll、.exe都装配件。

  装配件和命名空间的关系不是一一对应,也不互相包含,一个装配件里面可以有多个命名空间,一个命名空间也可以在多个装配件中存在,这样说可能有点模糊,举个例子: 

装配件A:

     namespace N1 

     { 

      public class AC1 {…} 

      public class AC2 {…} 

     } 

    namespace N2 

    { 

       public class AC3 {…} 

      public class AC4{…} 

    } 

装配件B: 

     namespace N1 

    {      

      public class BC1 {…} 

      public class BC2 {…} 

    } 

    namespace N2 

    { 

      public class BC3 {…} 

      public class BC4{…} 

     }

  这两个装配件中都有N1和N2两个命名空间,而且各声明了两个类,这样是完全可以的,然后我们在一个应用程序中引用装配件A,那么在这个应用程序中,我们能看到N1下面的类为AC1和AC2,N2下面的类为AC3和AC4。  接着我们去掉对A的引用,加上对B的引用,那么我们在这个应用程序下能看到的N1下面的类变成了BC1和BC2,N2下面也一样。  如果我们同时引用这两个装配件,那么N1下面我们就能看到四个类:AC1、AC2、BC1和BC2。

  到这里,我们可以清楚一个概念了,命名空间只是说明一个类型是那个族的,比如有人是汉族、有人是回族;而装配件表明一个类型住在哪里,比如有人住在北京、有人住在上海;那么北京有汉族人,也有回族人,上海有汉族人,也有回族人,这是不矛盾的。

  上面我们说了,装配件是一个类型居住的地方,那么在一个程序中要使用一个类,就必须告诉编译器这个类住在哪儿,编译器才能找到它,也就是说必须引用该装配件。  那么如果在编写程序的时候,也许不确定这个类在哪里,仅仅只是知道它的名称,就不能使用了吗?答案是可以,这就是反射了,就是在程序运行的时候提供该类型的地址,而去找到它。  有兴趣的话,接着往下看吧。

 

3、运行期得到类型信息有什么用 

  有人也许疑问,既然在开发时就能够写好代码,干嘛还放到运行期去做,不光繁琐,而且效率也受影响。  这就是个见仁见智的问题了,就跟早绑定和晚绑定一样,应用到不同的场合。有的人反对晚绑定,理由是损耗效率,但是很多人在享受虚函数带来的好处的时侯还没有意识到他已经用上了晚绑定。这个问题说开去,不是三言两语能讲清楚的,所以就点到为止了。  我的看法是,晚绑定能够带来很多设计上的便利,合适的使用能够大大提高程序的复用性和灵活性,但是任何东西都有两面性,使用的时侯,需要再三衡量。

  接着说,运行期得到类型信息到底有什么用呢?  还是举个例子来说明,很多软件开发者喜欢在自己的软件中留下一些接口,其他人可以编写一些插件来扩充软件的功能,比如我有一个媒体播放器,我希望以后可以很方便的扩展识别的格式,那么我声明一个接口: 

    public interface IMediaFormat 

    { 

      string Extension {get;} 

      Decoder GetDecoder();    

    } 

  这个接口中包含一个Extension属性,这个属性返回支持的扩展名,另一个方法返回一个解码器的对象(这里我假设了一个Decoder的类,这个类提供把文件流解码的功能,扩展插件可以派生之),通过解码器对象我就可以解释文件流。  那么我规定所有的解码插件都必须派生一个解码器,并且实现这个接口,在GetDecoder方法中返回解码器对象,并且将其类型的名称配置到我的配置文件里面。  这样的话,我就不需要在开发播放器的时侯知道将来扩展的格式的类型,只需要从配置文件中获取现在所有解码器的类型名称,而动态的创建媒体格式的对象,将其转换为IMediaFormat接口来使用。 
这就是一个反射的典型应用。 

 

4、如何使用反射获取类型 

  首先我们来看如何获得类型信息。  获得类型信息有两种方法,一种是得到实例对象  这个时侯我仅仅是得到这个实例对象,得到的方式也许是一个object的引用,也许是一个接口的引用,但是我并不知道它的确切类型,我需要了解,那么就可以通过调用System.Object上声明的方法GetType来获取实例对象的类型对象,比如在某个方法内,我需要判断传递进来的参数是否实现了某个接口,如果实现了,则调用该接口的一个方法: 

  …  public void Process( object processObj ) 

    { 

      Type t = processsObj.GetType(); 

      if( t.GetInterface(“ITest”) !=null )  … 

    }  … 

  另外一种获取类型的方法是通过Type.GetType以及Assembly.GetType方法,如: 

    Type t = Type.GetType(“System.String”); 

  需要注意的是,前面我们讲到了命名空间和装配件的关系,要查找一个类,必须指定它所在的装配件,或者在已经获得的Assembly实例上面调用GetType。  本装配件中类型可以只写类型名称,另一个例外是mscorlib.dll,这个装配件中声明的类型也可以省略装配件名称(.Net装配件编译的时候,默认都引用了mscorlib.dll,除非在编译的时候明确指定不引用它),比如:  System.String是在mscorlib.dll中声明的,上面的

  Type t = Type.GetType(“System.String”)

  是正确的  System.Data.DataTable是在System.Data.dll中声明的,那么: 

  Type.GetType(“System.Data.DataTable”)

就只能得到空引用。  必须: 

  Type t = Type.GetType("System.Data.DataTable,System.Data,Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"); 

  这样才可以,大家可以看下面这个帖子:  http://search.youkuaiyun.com/Expert/topic/2210/2210762.xml?temp=.1919977  qqchen的回答很精彩

 

5、如何根据类型来动态创建对象 

  System.Activator提供了方法来根据类型动态创建对象,比如创建一个DataTable:

  Type t = Type.GetType("System.Data.DataTable,System.Data,Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");

DataTable table = (DataTable)Activator.CreateInstance(t);

  例二:根据有参数的构造器创建对象 

    namespace TestSpace

    { 

      public class TestClass 

       { 

        private string _value; 

        public TestClass(string value)

        { 

           _value=value; 

        } 

      } 

    } 

      … 

      Type t = Type.GetType(“TestSpace.TestClass”); 

      Object[] constructParms = new object[] {“hello”};

      //构造器参数 

      TestClass obj = (TestClass)Activator.CreateInstance(t,constructParms); 

      … 

   把参数按照顺序放入一个Object数组中即可 

 

6、如何获取方法以及动态调用方法    

    namespace TestSpace 

     { 

      public class TestClass

      { 

        private string _value; 

        public TestClass() {  } 

        public TestClass(string value)

        { 

          _value = value; 

         }

      public string GetValue( string prefix )

       { 

        if( _value==null ) 

           return "NULL"; 

         else 

          return prefix+" : "+_value; 

      }

      public string Value

      { 

        set

        { 

          _value=value; 

        } 

        get

         { 

           if( _value==null ) 

            return "NULL"; 

          else 

             return _value; 

         } 

       } 

     } 

  }

  上面是一个简单的类,包含一个有参数的构造器,一个GetValue的方法,一个Value属性,我们可以通过方法的名称来得到方法并且调用之,

  如://获取类型信息 

    Type t = Type.GetType("TestSpace.TestClass"); 

    //构造器的参数 

    object[] constuctParms = new object[]{"timmy"}; 

    //根据类型创建对象 

    object dObj = Activator.CreateInstance(t,constuctParms); 

    //获取方法的信息 

    MethodInfo method = t.GetMethod("GetValue"); 

     //调用方法的一些标志位,这里的含义是Public并且是实例方法,这也是默认的值 

    BindingFlags flag = BindingFlags.Public | BindingFlags.Instance; 

     //GetValue方法的参数 

     object[] parameters = new object[]{"Hello"}; 

    //调用方法,用一个object接收返回值 

     object returnValue = method.Invoke(dObj,flag,Type.DefaultBinder,parameters,null);

属性与方法的调用大同小异,大家也可以参考MSDN

 

7、动态创建委托 

  委托是C#中实现事件的基础,有时候不可避免的要动态的创建委托,实际上委托也是一种类型:System.Delegate,所有的委托都是从这个类派生的  System.Delegate提供了一些静态方法来动态创建一个委托,比如一个委托:

  namespace TestSpace

  { 

    delegate string TestDelegate(string value); 

    public class TestClass

    { 

       public TestClass() {  } 

      public void GetValue(string value)

      { 

         return value; 

       } 

    } 

  } 
  使用示例:  TestClass obj = new TestClass(); 
  //获取类型,实际上这里也可以直接用typeof来获取类型 

  Type t = Type.GetType(“TestSpace.TestClass”); 

  //创建代理,传入类型、创建代理的对象以及方法名称 

  TestDelegate method = (TestDelegate)Delegate.CreateDelegate(t,obj,”GetValue”);

  String returnValue = method(“hello”);

 

到这里,我们简单的讲述了反射的作用以及一些基本的用法,还有很多方面没有涉及到,有兴趣的朋友可以参考MSDN。

转载于:https://www.cnblogs.com/tzh521241/archive/2012/07/17/Reflection.html

使用python读取卫星测高数据并做相应的处理 5.在python处理结果如下,最大的优点就是比matlab快30-40倍。4.进行粗差的如NaN值,还有进行3倍方差进行对粗差处理。1.首先遍历卫星数据的文件,挨个读取每个数据。有问题,请各位读者及时告知,一起完善内容。3.进行下一步,筛选在研究区域的数据。4.进行按天求平均和按月求平均。2.读取数据主体代码。 阅读详情

相关推荐

MT5交易软件系统源码

Manager配置的功能及权限:管理客户、开户,销户、入金、信用额度、修改定单、人工交易报表、设定点差、强制平仓、修改密码,设定持仓交割单或挂单小止盈止损点数;26、修改价格 27、更改K线图历史价格 28、同步历史数据;2、系统设置 3、交易管理 4、交易柜台 5、价格更改 6、多台服。务器联机 7、恢复交易历史 8、数据源调整 9、备份服务调整 10、交易市场设定 11、交易单更改 12、平台时间设定(全世界) 13、可添加商品;15、设置商品利息;独立主机(服务器、VPS、VM)

tutujunjun的博客 904

浅谈.Net反射

相比较下,引用执行效率高,但是当你引用的dll文件很多的时候,一遍遍的引用dll...,那就不是什么好事了。 反射呢,虽执行效率低,但在上述情况出现时,它只需动态反射一次dll文件,不用去管dll文件时新增还是减少的情况了               二.那些反射用到的类

兔兔耶耶 4167

手把手教你编写I2C读写EEPROM代码(驱动层实现)

从底层寄存器配置到时序控制,详解如何编写可移植的I2C读写EEPROM代码,覆盖起始信号、地址帧、数据收发及ACK应答等关键环节,确保在STM32、ESP32等主流平台稳定运行,真正落地i2c读写eeprom代码需求。

weixin_35756130的博客 507

.NET技术----反射

1、什么是反射反射的定义:审查元数据并收集关于它的类型信息的能力。元数据(编译以后的最基本数据单元)就是一大堆的表,当编译程序集或者模块时,编译器会创建一个类定义表,一个字段定义表,和一个方法定义表等,。System.reflection命名空间包含的几个类,允许你反射(解析)这些元数据表的代码 和反射相关的命名空间(我们就是通过这几个命名空间访问反射信息): System.Reflectio

happyxzxin的专栏 828

MATLAB与STK互联23:卫星对象操作(14)—仿真分析案例1,建立8个地面站,分析对卫星的可见性

学习到这里,我们有必要做个仿真分析案例,把之前我们学习的零散知识点串起来,看一下在真实的分析中怎么应用。 分析要求:建立8个地面站,分析每个地面站对某个轨道高度500km、倾角60°圆轨道的卫星,1天内的可见次数、可见弧长以及可见弧段间隔列表。 基本约束:地面站仰角8°~90°,作用距离<2000km,太阳矢量与地面站到卫星视线夹角不小于15°,可见弧段应大于30s。地面站站址可随机生成,但要求在南北纬50°范围内。 下面上代码: uiap = actxserver(‘STK11.application’)

ltylty001的博客 7491

基于 OptiSystem 的掺铒光纤放大器(EDFA)分析

通过构建 EDFA 仿真模型,系统分析了铒离子掺杂半径、离子浓度、光纤长度及泵浦功率等关键参数对放大器增益和噪声特性的影响规律,为 EDFA 的优化设计提供了理论依据与仿真支撑。继续增大至 9μm,增益趋于稳定(约 19dB)。继续增加至 200mW,增益仅增加 2dB,表明泵浦功率存在阈值效应(约 100mW),超过后增益饱和明显。:作为增益介质,主要参数包括光纤长度(5~50m)、铒离子掺杂半径(1~10μm)、离子浓度(1×10²⁵~5×10²⁵m⁻³)、纤芯半径 2.2μm、数值孔径 0.24。

2501_91855190的博客 2676

【转】反射

反射是.NET中的重要机制,通过反射,可以在运行时获得程序或程序集中每一个类型(包括类、结构、委托、接口和枚举等)的成员和成员的信息。有了反射,即可对每一个类型了如指掌。另外我还可以直接创建对象,即使这个对象的类型在编译时还不知道。 反射的用途: (1)使用Assembly定义和加载程序集,加载在程序集清单中列出模块,以及从此程序集中查找类型并创建该类型的实例。 (2)使用M...

weixin_30312563的博客 560

lammps模拟技巧:高熵合金势函数设置三种方法

大家好,我是小马老师。 本文继续介绍lammps模拟中的势函数设置方法。 在前面的文章中,介绍过高熵合金的建模:高熵合金建模 高熵合金包含的原子数较多,势函数的设置相对复杂,在平时一对一的咨询中,这种问题也相对较多。 下面介绍三种高熵合金势函数设置方法。 1.下载专用势函数 下面的网站包含了大多数原子的势函数: https://www.ctcms.nist.gov/potentials/ 如需下载包含Fe原子的势函数,直接点Fe: 出现势函数列表: 比如Al-Co-Cr-Fe-Ni就是高熵合金AlCoC

lammps_jiayou的博客 8962

.NET 中的反射

.NET 中的反射

程序员思维的博客 820

【教程4>第7章>第6节】基于FPGA的Viterbi维特比译码verilog实现——ACS加比选单元1

本文介绍了ACS加比选单元模块在FPGA中的实现过程,重点讲解了维特比译码中的ACS单元功能及其在硬件实现中的关键问题。文章首先概述了ACS单元在维特比译码中的作用,即通过计算和比较分支度量值来选择最优路径。接着,详细描述了FPGA实现中的分支度量值归一化处理策略,并指出了其存在的弊端。随后,文章提供了基于Verilog的ACS加比选单元模块代码,解释了其输入输出端口及工作流程。最后,总结了本小节内容,并预告了下一章节将涉及ACS顶层模块的开发与仿真测试。

FPGA/MATLAB学习教程/源码/项目合作开发 568

图神经网络与大模型融合的理论综述:架构、机制与未来方向

然而,它们普遍缺乏对图结构数据的原生支持,无法直接处理边、节点之间的拓扑关系,这限制了其在关系密集型任务中的表现 [23]。2020年发布的BERT [16] 开启了自监督预训练时代,而2021年后,T5 [17]、PaLM [18]、LLaMA [19] 等模型相继推出,参数规模突破千亿级,展现出惊人的上下文学习(In-context Learning)与链式推理(Chain-of-Thought)能力 [20]。例如,将医学影像作为图节点,结合病理报告文本,实现更精准的疾病诊断 [58]。

andeyeluguo的博客 295

.net反射简介 - 概述

.net反射简介 - 概述       反射就是动态发现类型信息的能力。它帮助程序设计人员在程序运行时利用一些信息去动态地使用类型,这些信息在设计时是未知的,这种能力类型于后期绑定。反射还支持的更高级的行为,能在运行时动态创建新类型,并且对这些新类型的操作进行调用。编辑本段   回目录   .net反射简介 - 一些在反射中经常使用的类Assembly类      Asse

ghfsusan的专栏 4375

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

.net反射机制的简单介绍

1、什么是反射   Reflection,中文翻译为反射。这是.Net中获取运行时类型信息的方式,.Net的应用程序由几个部分: ‘程序集(Assembly)’、‘模块(Module)’、‘类型(class)’组成,而反射提供一种编程的方式,让程序员可以在程序运行期获得这几个组成部分的相关信息,例如:   Assembly类可以获得正在运行的装配件信息,也可以动态的加载装配件...

ading0210的博客 104

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

【C#】VS中.Net反射机制简单介绍

【C#】VS中.Net反射机制简单介绍 反射(Reflection)是. NET的重要机制之一,通过反射,可以在运行时获得.NET 中一个类型(包括类、结构、委托、接口和枚举等)的成员,包括方法、属性、事件,以及构造函数等,还可以获得每个成员的名称、限定符和参数等。 由于获取了构造函数的信息,因此可通过类名来直接创建对象,即使这个对象的类型在编译时是未知的。 由于在. NET的程序集(Assembly)中封装了类型元数据信息,因此可以先通过Assembly的Load("程序集名称”)方法加载一个程序集,再通

Power3sun的博客 322

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

vb.net 中通过反射实现简单工厂模式

      前天看了一个设计模式视频,是用Java实现简单工厂模式,要是用if……else来判断的话,改到.net下也是很好实现的,但是在Java里面用到了反射的机制,这样就省去了工厂内部或是客户端内对要生产东西的判断。直接根据传进来的参数既可以完成生产。下面我给出我做的例子,先给出一般的通过if ……else来判断的:Imports System.ReflectionImport

the_fire的技术博客 1859

【C#】:浅谈反射机制

什么是反射?         反射提供了封装程序集、模块和类型的对象(Type 类型)。可以使用反射动态创建类型的实例,将类型绑定到现有对象,或从现有对象获取类型并调用其方法或访问其字段和属性。如果代码中使用了属性,可以利用反射对它们进行访问。         反射机制是.Net中获取运行时类型信息的方式,.Net的应用程序由几个部分:‘程序集(Assembly)’、‘模块(Module)’、

爱技术 爱生活 9181

SharpSerializer:让.NET对象序列化更简单

SharpSerializer:让.NET对象序列化更简单 在.NET开发中,对象序列化是一个常见的需求,无论是将对象状态保存到文件、数据库还是进行网络传输,序列化都是必不可少的步骤。今天,我们就来介绍一个开源的.NET序列化库——SharpSerializer,它以其简单易用和强大的序列化能力,吸引了不少开发者的关注。 项目介绍 SharpSerializer是一个开源的.NET库,支持XML和...

gitblog_00672的博客 677

c++ so 反射_C++实现反射机制

.NET下的很多技术都是基于反射机制来实现的,反射让.NET平台下的语言变得得心应手。最简单的,比如枚举类型,我们我可以很容易的获得一个枚举变量的数值以及其名称字符串。可是,在C++中,枚举变量本质上和一个整形变量没有区别,我们很难获取一个枚举变量的名称字符串。其实在C++中,我们可以通过宏来实现类似反射的机制。接下来,我想总结一下如何在C++中实现一个类似于C#枚举类型的方法。__VA_ARGS...

weixin_39769187的博客 120

C#的反射机制调用方法

.NET的反射(Reflection)是非常完善和强大的,例如有名的.NET反编译工具Red Gate's .NET Reflector就是使用了.NET自身的反射机制,这里有一个比较简单的实例(使用控制台程序),看看.NET中如何使用反射。 using System; using System.Reflection; namespace Mengliao.CSharp.C13.S...

weixin_33857679的博客 107

C#反射机制

1、定义 反射是.NET中的重要机制,通过反射,可以在运行时获得程序或程序集中每一个类型(包括类、结构、委托、接口和枚举等)的成员和成员的信息。 有了反射,即可了解类型,还可以创建实例对象,调用类型中的方法等。 2、命名空间 反射用到的命名空间: System.Reflection 3、常用的类 1)Assembly:加载程序集 2)ConstructorInfo:了解构造函数相关的信息 3)Me...

qq_43026206的博客 568

C++实现反射机制(一)

NET下的很多技术都是基于反射机制来实现的,反射让.NET平台下的语言变得得心应手。最简单的,比如枚举类型,我们我可以很容易的获得一个枚举变量的数值以及其名称字符串。 可是,在C++中,枚举变量本质上和一个整形变量没有区别,我们很难获取一个枚举变量的名称字符串。 其实在C++中,我们可以通过宏来实现类似反射的机制。 接下来,我想总结一下如何在C++中实现一个类似于C#枚举类型的方法。 __

王伟挺的专栏 3301

设计模式培训之二:简单工厂、工厂方法

查看本人文章索引请通过http://www.cnblogs.com/seesea125/archive/2012/04/17/2453256.html 一、简单工厂和工厂方法定义: 简单工厂模式是由一个工厂类根据参数来决定创立出哪一种产品类的实例。 工厂方法模式通过调用不同的方法返回需要的类,而不是去实例化具体的类。 对实例创建进行了包装。 工厂方法是一组方法, 他们针对不同条件返回不同的类...

weixin_30662109的博客 64

让程序语言的反射机制融入生活

写在开始: 小菜在看java视频的时候发现很多地方提到反射,虽然在.net 中用到过反射,我们的七层架构(简单工厂改造抽象工厂模式+配置文件)中用到了反射。而在学习java的时候也多次谈到反射。Net中的都不是十分的理解,这让小菜就有些 了,雾里看花,水中看月一般~~~    其实,我们仔细思考一下,不难发现,反射就在我们身边~~~   啥是反射???丫丫的。。 反射,我们抛开计算机

Xinghf 2831

.net中实现运行时从字符串动态创建对象

看到标题,大部分会说“运行时创建对象”那不是小儿科,就这样: Dim newButton As Button = New Button() newButton.Name = "Button1" 这的确是在运行时创建了一个按钮。不过若需按照用户要求创建按钮、复选框或者单选框怎么办,好像也好办: Dim newControl As Control Select

Ninputer的专栏 1835

反射机制和MetaData的简单利用

Atommmm的博客 453

使用反射机制实现jQuery调用ashx类中的指定方法

近期用asp.net做个小网站,但又不喜欢使用asp.net的服务器端控件,经过一番思量后确定前端采用原始的html、后台采用Linq to Sql与数据库交互,Linq上面创建一业务逻辑层,而web前端通过使用jQuery的ajax方法异步调用asp.net的一般处理程序(handler),实现与后台的业务逻辑层交互,至此大方向开发框架确立,只是细节上jQuery调用ashx有点小麻烦,一次只能...

weixin_30613343的博客 228
下一篇: 设计模式之单例模式--Singleton Pattern
datuo2821
博客等级 码龄11年 0粉丝 0原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值