关于事件与委托的概念性问题

C#委托与事件:原理、实现与应用全解析 委托(delegate)是C#中的类型安全函数指针,实现了方法的间接调用和多播能力,为事件驱动编程奠定基础。事件(event)基于委托构建了发布-订阅模型,遵循观察者模式实现对象间松耦合通信。在C#中,委托支持协变与逆变,事件则通过标准模式或泛型EventHandler<T>实现。多播委托特性允许组合多个方法调用,而弱事件模式解决了常见的内存泄漏问题。这些机制广泛应用于UI交互、异步编程和领域驱动设计,特别是在WPF路由事件、ASP.NET Core中间件等现代框架中。理解委托与事件的底层原理,包括CLR处 阅读详情

回答:

从前,在南方一块奇异的土地上,有个工人名叫彼得,他非常勤奋,对他的老板总是百依百顺。但是他的老板是个吝啬的人,从不信任别人,坚决要求随时知道彼得的工作进度,以防止他偷懒。但是彼得又不想让老板呆在他的办公室里站在背后盯着他,于是就对老板做出承诺:无论何时,只要我的工作取得了一点进展我都会及时让你知道。彼得通过周期性地使用“带类型的引用”(原文为:“typed   reference”   也就是delegate??)“回调”他的老板来实现他的承诺,如下:

class   Worker   {
        public   void   Advise(Boss   boss)   {   _boss   =   boss;   }
        public   void   DoWork()   {
                Console.WriteLine(“工作:   工作开始”);
                if(   _boss   !=   null   )   _boss.WorkStarted();

                Console.WriteLine(“工作:   工作进行中”);
                if(   _boss   !=   null   )   _boss.WorkProgressing();

                Console.WriteLine("“工作:   工作完成”");
                if(   _boss   !=   null   )   {
                        int   grade   =   _boss.WorkCompleted();
                        Console.WriteLine(“工人的工作得分=”     grade);
        }
}
private   Boss   _boss;
}

class   Boss   {
        public   void   WorkStarted()   {   /*   老板不关心。   */   }
        public   void   WorkProgressing()   {   /*老板不关心。   */   }
        public   int   WorkCompleted()   {
                Console.WriteLine(“时间差不多!”);
                return   2;   /*   总分为10   */
        }
}

class   Universe   {
        static   void   Main()   {
                Worker   peter   =   new   Worker();
                Boss   boss   =   new   Boss();
                peter.Advise(boss);
                peter.DoWork();

                Console.WriteLine(“Main:   工人工作完成”);
                Console.ReadLine();
        }
}
接口

  现在,彼得成了一个特殊的人,他不但能容忍吝啬的老板,而且和他周围的宇宙也有了密切的联系,以至于他认为宇宙对他的工作进度也感兴趣。不幸的是,他必须也给宇宙添加一个特殊的回调函数Advise来实现同时向他老板和宇宙报告工作进度。彼得想要把潜在的通知的列表和这些通知的实现方法分离开来,于是他决定把方法分离为一个接口:

interface   IWorkerEvents   {
        void   WorkStarted();
        void   WorkProgressing();
        int   WorkCompleted();
}

class   Worker   {
        public   void   Advise(IWorkerEvents   events)   {   _events   =   events;   }
        public   void   DoWork()   {
                Console.WriteLine(“工作:   工作开始”);
                if(   _events   !=   null   )   _events.WorkStarted();

                Console.WriteLine(“工作:   工作进行中”);
                if(_events   !=   null   )   _events.WorkProgressing();

                Console.WriteLine("“工作:   工作完成”");
                if(_events   !=   null   )   {
                        int   grade   =   _events.WorkCompleted();

                        Console.WriteLine(“工人的工作得分=”     grade);
                        }
        }
        private   IWorkerEvents   _events;
}

class   Boss   :   IWorkerEvents   {
        public   void   WorkStarted()   {   /*   老板不关心。   */   }
        public   void   WorkProgressing()   {   /*   老板不关心。   */   }
        public   int   WorkCompleted()   {
                Console.WriteLine(“时间差不多!”);
                return   3;   /*   总分为10   */
        }
}


委托

  不幸的是,每当彼得忙于通过接口的实现和老板交流时,就没有机会及时通知宇宙了。至少他应该忽略身在远方的老板的引用,好让其他实现了IWorkerEvents的对象得到他的工作报告。(”At   least   he "d   abstracted   the   reference   of   his   boss   far   away   from   him   so   that   others   who   implemented   the   IWorkerEvents   interface   could   be   notified   of   his   work   progress”   原话如此,不理解到底是什么意思   )

  他的老板还是抱怨得很厉害。“彼得!”他老板吼道,“你为什么在工作一开始和工作进行中都来烦我?!我不关心这些事件。你不但强迫我实现了这些方法,而且还在浪费我宝贵的工作时间来处理你的事件,特别是当我外出的时候更是如此!你能不能不再来烦我?”

  于是,彼得意识到接口虽然在很多情况都很有用,但是当用作事件时,“粒度”不够好。他希望能够仅在别人想要时才通知他们,于是他决定把接口的方法分离为单独的委托,每个委托都像一个小的接口方法:

delegate   void   WorkStarted();
delegate   void   WorkProgressing();
delegate   int   WorkCompleted();

class   Worker   {
        public   void   DoWork()   {
                Console.WriteLine(“工作:   工作开始”);
                if(   started   !=   null   )   started();

                Console.WriteLine(“工作:   工作进行中”);
                if(   progressing   !=   null   )   progressing();

                Console.WriteLine("“工作:   工作完成”");
                if(   completed   !=   null   )   {
                        int   grade   =   completed();
                        Console.WriteLine(“工人的工作得分=”     grade);
                }
        }
        public   WorkStarted   started;
        public   WorkProgressing   progressing;
        public   WorkCompleted   completed;
}

class   Boss   {
        public   int   WorkCompleted()   {
        Console.WriteLine("Better...");
        return   4;   /*   总分为10   */
}
}

class   Universe   {
        static   void   Main()   {
                Worker   peter   =   new   Worker();
                Boss   boss   =   new   Boss();
                peter.completed   =   new   WorkCompleted(boss.WorkCompleted);
                peter.DoWork();

                Console.WriteLine(“Main:   工人工作完成”);
                Console.ReadLine();
        }
}
静态监听者

  这样,彼得不会再拿他老板不想要的事件来烦他老板了,但是他还没有把宇宙放到他的监听者列表中。因为宇宙是个包涵一切的实体,看来不适合使用实例方法的委托(想像一下,实例化一个“宇宙”要花费多少资源…..),于是彼得就需要能够对静态委托进行挂钩,委托对这一点支持得很好:

class   Universe   {
        static   void   WorkerStartedWork()   {
                Console.WriteLine("Universe   notices   worker   starting   work");
        }

        static   int   WorkerCompletedWork()   {
                Console.WriteLine("Universe   pleased   with   worker "s   work");
                return   7;
        }

        static   void   Main()   {
                Worker   peter   =   new   Worker();
                Boss   boss   =   new   Boss();
                peter.completed   =   new   WorkCompleted(boss.WorkCompleted);
                peter.started   =   new   WorkStarted(Universe.WorkerStartedWork);
                peter.completed   =   new   WorkCompleted(Universe.WorkerCompletedWork);
                peter.DoWork();

                Console.WriteLine(“Main:   工人工作完成”);
                Console.ReadLine();
        }
}

回答:

事件

  不幸的是,宇宙太忙了,也不习惯时刻关注它里面的个体,它可以用自己的委托替换了彼得老板的委托。这是把彼得的Worker类的的委托字段做成public的一个无意识的副作用。同样,如果彼得的老板不耐烦了,也可以决定自己来激发彼得的委托(真是一个粗鲁的老板):

//   Peter "s   boss   taking   matters   into   his   own   hands
if(   peter.completed   !=   null   )   peter.completed();

  彼得不想让这些事发生,他意识到需要给每个委托提供“注册”和“反注册”功能,这样监听者就可以自己添加和移除委托,但同时又不能清空整个列表也不能随意激发彼得的事件了。彼得并没有来自己实现这些功能,相反,他使用了event关键字让C#编译器为他构建这些方法:

class   Worker   {
...
        public   event   WorkStarted   started;
        public   event   WorkProgressing   progressing;
        public   event   WorkCompleted   completed;
}

  彼得知道event关键字在委托的外边包装了一个property,仅让C#客户通过 =   和   -=操作符来添加和移除,强迫他的老板和宇宙正确地使用事件。

static   void   Main()   {
        Worker   peter   =   new   Worker();
        Boss   boss   =   new   Boss();
        peter.completed   =   new   WorkCompleted(boss.WorkCompleted);
        peter.started   =   new   WorkStarted(Universe.WorkerStartedWork);
        peter.completed   =   new   WorkCompleted(Universe.WorkerCompletedWork);
        peter.DoWork();

        Console.WriteLine(“Main:   工人工作完成”);
        Console.ReadLine();
}
“收获”所有结果

  到这时,彼得终于可以送一口气了,他成功地满足了所有监听者的需求,同时避免了与特定实现的紧耦合。但是他注意到他的老板和宇宙都为它的工作打了分,但是他仅仅接收了一个分数。面对多个监听者,他想要“收获”所有的结果,于是他深入到代理里面,轮询监听者列表,手工一个个调用:

public   void   DoWork()   {
        ...
        Console.WriteLine("“工作:   工作完成”");
        if(   completed   !=   null   )   {
                foreach(   WorkCompleted   wc   in   completed.GetInvocationList()   )   {
                        int   grade   =   wc();
                        Console.WriteLine(“工人的工作得分=”     grade);
                }
        }
}

异步通知:激发   &   忘掉

  同时,他的老板和宇宙还要忙于处理其他事情,也就是说他们给彼得打分所花费的事件变得非常长:

class   Boss   {
        public   int   WorkCompleted()   {
                System.Threading.Thread.Sleep(3000);
                Console.WriteLine("Better...");   return   6;   /*   总分为10   */
        }
}

class   Universe   {
        static   int   WorkerCompletedWork()   {
                System.Threading.Thread.Sleep(4000);
                Console.WriteLine("Universe   is   pleased   with   worker "s   work");
                return   7;
        }
        ...
}

  很不幸,彼得每次通知一个监听者后必须等待它给自己打分,现在这些通知花费了他太多的工作事件。于是他决定忘掉分数,仅仅异步激发事件:

public   void   DoWork()   {
        ...
        Console.WriteLine("“工作:   工作完成”");
        if(   completed   !=   null   )   {
                foreach(   WorkCompleted   wc   in   completed.GetInvocationList()   )
                {
                        wc.BeginInvoke(null,   null);
                }
        }
}
异步通知:轮询

  这使得彼得可以通知他的监听者,然后立即返回工作,让进程的线程池来调用这些代理。随着时间的过去,彼得发现他丢失了他工作的反馈,他知道听取别人的赞扬和努力工作一样重要,于是他异步激发事件,但是周期性地轮询,取得可用的分数。

public   void   DoWork()   {
        ...
        Console.WriteLine("“工作:   工作完成”");
        if(   completed   !=   null   )   {
                foreach(   WorkCompleted   wc   in   completed.GetInvocationList()   )   {
                        IAsyncResult   res   =   wc.BeginInvoke(null,   null);
                        while(   !res.IsCompleted   )   System.Threading.Thread.Sleep(1);
                        int   grade   =   wc.EndInvoke(res);
                        Console.WriteLine(“工人的工作得分=”     grade);
                }
        }
}
异步通知:委托

  不幸地,彼得有回到了一开始就想避免的情况中来,比如,老板站在背后盯着他工作。于是,他决定使用自己的委托作为他调用的异步委托完成的通知,让他自己立即回到工作,但是仍可以在别人给他的工作打分后得到通知:

        public   void   DoWork()   {
                ...
                Console.WriteLine("“工作:   工作完成”");
                if(   completed   !=   null   )   {
                        foreach(   WorkCompleted   wc   in   completed.GetInvocationList()   )   {
                                wc.BeginInvoke(new   AsyncCallback(WorkGraded),   wc);
                        }
                }
        }

        private   void   WorkGraded(IAsyncResult   res)   {
                WorkCompleted   wc   =   (WorkCompleted)res.AsyncState;
                int   grade   =   wc.EndInvoke(res);
                Console.WriteLine(“工人的工作得分=”     grade);
        }
宇宙中的幸福

  彼得、他的老板和宇宙最终都满足了。彼得的老板和宇宙可以收到他们感兴趣的事件通知,减少了实现的负担和非必需的往返“差旅费”。彼得可以通知他们,而不管他们要花多长时间来从目的方法中返回,同时又可以异步地得到他的结果。彼得知道,这并不*十分*简单,因为当他异步激发事件时,方法要在另外一个线程中执行,彼得的目的方法完成的通知也是一样的道理。但是,迈克和彼得是好朋友,他很熟悉线程的事情,可以在这个领域提供指导。

  他们永远幸福地生活下去…… <完 > 
从编排到委托:OpenClaw如何重塑AI Agent开发范式 在AI应用开发领域,大语言模型(LLM)和智能体(Agent)技术正推动着开发范式的演进。传统API调用遵循“编排者”模式,开发者需要像导演一样预先编写所有执行步骤、处理分支逻辑和异常,控制粒度细但维护成本高。其核心原理是通过确定性代码流程串联多个服务调用,技术价值在于对执行过程的完全掌控,适用于线性、高确定性的场景。然而,随着应用复杂度提升,涉及多步骤、动态规划和频繁工具交互的任务日益增多,传统模式面临心智负担重、扩展性差的挑战。此时,“委托者”范式应运而生,它将“如何做”的具体执行逻辑委托给具备自主规划 阅读详情

相关推荐

人形机器人专题:人形机器人关节,从Optimus选型看关节的发展

今天分享的是深度研究报告:《(报告出品方:中泰页。

GPT20236688的博客 3223

委托事件的三个很好的例子

今天在csdn的论坛看到的帖子,写的不错,就贴上来了。http://community.youkuaiyun.com/Expert/topic/4093/4093184.xml?temp=.38435两个例子均用现实的例子来解释委托事件的处理过程。很好!  第一个例子public delegate void EatEventHandler(object sender, EatEventArgs e);

动性忍心 2332

【第三只眼:Oracle通过归档日志查看系统的业务高峰sql】

根据oracle归档的业务高峰量,查找业务sql,进行优化

霍然的专栏 577

一个C#睡前故事[转载]

紧耦合   从前,在南方一块奇异的土地上,有个工人名叫彼得,他非常勤奋,对他的老板总是百依百顺。但是他的老板是个吝啬的人,从不信任别人,坚决要求随时知道彼得的工作进度,以防止他偷懒。但是彼得又不想让老板呆在他的办公室里站在背后盯着他,于是就对老板做出承诺:无论何时,只要我的工作取得了一点进展我都会及时让你知道。彼得通过周期性地使用“带类型的引用”(原文为:“typedreference”也就是...

weixin_30699465的博客 141

MOOS-ivp 实验三 MOOS简介(3)

MOOS-ivp 实验三 MOOS简介(3) 继上一篇文章继续对实验进行记录 提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录MOOS-ivp 实验三 MOOS简介(3)六、A Simple Example with pXRelay1.pXRelay基本使用2.pXRelay简单例子3.pXRelay实验七、First Experiments in Modifying MOOS App Code1.下载一个MOOS模板文件2.打开MOOS模板文件总结 六、A Simple E

weixin_44151170的博客 2534

TestFlight分发测试app,提示无法安装 所请求的App不可用或者不存在

TestFlight分发测试app,提示无法安装 所请求的App不可用或者不存在

天穹云原生 9168

关于事件与委托的概念性问题(精彩的讲解)

从前,在南方一块奇异的土地上,有个工人名叫彼得,他非常勤奋,对他的老板总是百依百顺。但是他的老板是个吝啬的人,从不信任别人,坚决要求随时知道彼得的工作进度,以防止他偷懒。但是彼得又不想让老板呆在他的办公室里站在背后盯着他,于是就对老板做出承诺:无论何时,只要我的工作取得了一点进展我都会及时让你知道。彼得通过周期性地使用“带类型的引用”(原文为:“typed reference” 也就是delega

354

rk3568 RGMII KSZ8795 MAC TO MAC

参考《Rockchip_Developer_Guide_Linux_MAC_TO_MAC_CN.pdf》

明天乌儿会歌唱 6491

趣味故事理解.NET概念——关于.NET接口、事件与委托的概念性问题

趣味故事理解.NET概念——关于.NET接口、事件与委托的概念性问题从前,在南方一块奇异的土地上,有个工人名叫彼得,他非常勤奋,对他的老板总是百依百顺。但是他的老板是个吝啬的人,从不信任别人,坚决要求随时知道彼得的工作进度,以防止他偷懒。但是彼得又不想让老板呆在他的办公室里站在背后盯着他,于是就对老板做出承诺:无论何时,只要我的工作取得了一点进展我都会及时让你知道。彼得通过周期性地使用“带类型

642

基于Zemax的干涉仪仿真——Fizeau球面干涉仪

最近在用Zemax仿真干涉仪,在这之前查资料都是关于一些平面干涉仪的仿真,很少有关于Fizeau型的,尤其是球面干涉仪的仿真,看到很多关于这方面的问题回复都说利用多重结构仿照Zemax马赫-泽德干涉仪去做,但是也没有具体的过程,因此在这里分享一下我仿真的干涉仪步骤方法,具体是利用多重结构完成的仿真。

weixin_46657737的博客 6407

【网络安全】零基础入门网络安全劝退指北

作为从16年接触网络安全的小白,谈谈零基础如何入门网络安全,有不对的地方,请多多指教。 这些年最后悔的事情莫过于没有把自己学习的东西积累下来形成一个知识体系。 后续我也会陆续的整理网络安全的相关学习资料及文章,与大家一起探讨学习。 如何入门 简单了解网络安全 网络安全就是指的确保网络系统中的数据不被别人破坏,而网安工程师就是涉及程序来维护网络安全。 网安方向有很多职位,比如安全产品工程师,安全分析师,数据恢复工程师,网络架构工程师,安全编程工程师,以及网络集成工程师等。 工作内容主要包括: 安全评测,风

互联网老辛 4580

mvc 事务层切换数据源_透传MVC架构---内部分享

关于MVC的文章,有点价值 https://zhuanlan.zhihu.com/p/58585650架构设计要点,是透传MVC架构的思维起点 https://zhuanlan.zhihu.com/p/73060146(该架构已经在局部模块取得了成功,之前所有文章中外对于MVC的论述,个人认为都是含糊不清的,本文清新论述了MVC,同时更重要的是对其做了很大的完善,希望回到你的点评,改正错误,填补不...

weixin_39557199的博客 108

【PostgreSQL教程】PostgreSQL 特别篇之 语言接口Java

本篇教程的Java程序中开始使用PostgreSQL之前,需要确保在计算机上设置了PostgreSQL JDBC和Java。您可以检查Java教程以在计算机上安装Java。现在让本篇教程检查如何设置PostgreSQL JDBC驱动程序。

No8g攻城狮的博客 1752

委托与事件

学习了.NET这么久,却一直对委托和事件两个概念一知半解,今天就仔细研究了下,写出来与大家分享: 委托和事件的概念性的东东: 1、委托是对函数的封装,可以看作是给方法特征的一个名称, 2、委托是一种引用方法类型(委托是引用类型,创建实例时用new),一旦为委托分配了方法,委托就与该方法具有完全相同的行为, 3、事件是委托类型的对象,类或对象可以通过事件通知其他类或对象发生相...

dingxiao4002的博客 120

jre9下载 jdk9

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

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

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

c#关于委托、事件的项目练习demo

关于委托、事件概念理解以及项目练习demo

KJJfighting的博客 1181

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

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

委托的自己理解

面试的时候估计都会被问过,什么是委托,事件是不是一种委托?委托的优点都是什么?我在项目中经常使用,但是平时不注意整理概念性知识,回答起来像是囫囵吞枣,答不出个所以然来。今天周末抽出来一些时间,静下心来整理下。下面我将采用一问一答的性质来整理和记录。 1.什么是委托? 委托是一种类型安全的对象,它是指向程序中的以后会被调用的函数方法(可以是多个)。 2.事件是不是一种委托? 是,是一种特殊...

ElegantHedgehog的博客 138

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

C#知识体系(二)用案例来理解委托与事件

上一篇博客讲到了LinQ和lambda的常用方法还有很多我们未知但c#设计团队已经为我们封装好的类和方法。随着我们不断的熟悉C#语言,渐渐的就会接触到其他的知识点,委托、事件、反射、线程、同步,异步、IO、套接字。。。这些东西我们平常用到的不多,都是些概念性的东西,也许是因为不熟悉而可以回避了使用这些东西,不可否认的是 就算不用这些我们依然能想到问题的解决办法。但是几乎所有语言都会有这些概念,因...

weixin_30919429的博客 107

学习C#委托总结

学习C#委托总结 学过C了,对委托就比较有概念性的认识,C#中的委托其实类似于C中的函数指针,C中我们可以把函数进行指针化,但在C#中不允许这么操作,所以C#中委托是安全的,它并不是直接对内存进行指向,而是编成中间件代码,所以这一点C#比较好,我们应该把委托看成一个新的概念,类似于类,只不过是个特殊的类,它需要声明,然后构造的时候要有一个与声明的参数,返回值一样的方法作为参数进行构造即可.

清风一吹(清风博客) 805

委托的学习日志

2011-11-28 到底什么是委托?简单的理解可以为:用参数进行方法的调用 可是什么条件下合适用委托,以及委托的好处有哪些,以及日常应用开发那里会用到 在此过程中,又加深了一点关于同步异步的概念性了解 同步,就是说你的程序在执行某一个操作时一直等待直到操作完成。 异步,就是说程序在执行某一个操作时,只是发出开始的指令;由另外的并行程序执行这段代码,当完成时再通知调用者。 研究的博文...

weixin_34162629的博客 121

macOS Sequoia Gatekeeper深度解析:签名验证与四层策略机制

Gatekeeper是macOS核心的安全执行机制,本质是基于代码签名与公证(Notarization)的信任链校验系统,而非传统防火墙。其原理依托Apple ID绑定、自动公证沙盒检测和本地恶意软件哈希黑名单三重锚点,实现毫秒级离线验证。技术价值在于平衡安全性与可用性——既阻止未签名/篡改/吊销证书软件运行,又支持开发者合规分发。典型应用场景包括企业IT策略管理、开发者调试环境配置、第三方工具安全启用等。在macOS Sequoia中,Gatekeeper升级为内核级、系统级、用户级、应用级四层嵌套策略,

weixin_33882452的博客 380

C#概念性考题

1, 请你说说.NET中类和结构的区别?答:结构和类具有大体的语法,但是结构受到的限制比类要多。结构不能申明有默认的构造函数,为结构的副本是又编译器创建和销毁的,所以不需要默认的构造函数和析构函数。结构是值类型,所以对结构变量所做的改变不会影响其的原值,而类是应用类型,改变其变量的值会改变其原值。申明结构用Struck关键字,申明类用class关键字,向方法传递结构是时是通过值传递的,而不是通过引...

weixin_33711647的博客 85

事件 你怎么看?

一 前言 最近在阅读 ASP.NET 本质论 一书详了解了“处理管道”这一概念,处理管道是通过事件机制来实现的,事件?这个知识点对我来说只是听过这个词,但是很少自己全面了解过,到于用嘛,当初在asp.net 拖控件的时候用得是相当多啊。于是便全面了解了一下,其实事件应该与委托一起写的,但是当时并不了解事件所以就不知道它俩之间的关系。 不知不觉 XX 你怎么看?系列也写到第三篇了 委托 你怎么...

weixin_30337157的博客 96
上一篇: CSS样式里使用JavaScript
下一篇: css做的菜單
jackeyabc
博客等级 码龄20年 71粉丝 297原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值