ASP.NET EVAL性能

3台虚拟机部署Doris详细文档(含校验步骤) 摘要:本文详细介绍了Apache Doris在3台虚拟机上的集群部署方案。采用1主FE+1从FE+1观察者FE+3BE的混合部署模式,确保元数据高可用性。硬件配置建议测试环境4核16GB内存,生产环境8核64GB内存。部署步骤包括系统环境配置(关闭防火墙、内核参数优化)、FE/BE节点配置启动、集群初始化验证等。重点配置了IP白名单(172.30.0.115)和数据目录(/data/doris)。通过MySQL客户端和WebUI可监控集群状态,实现千万级数据的实时分析能力,后续可通过增加BE节点线性扩展。 阅读详情

 写ASP.NET中使用Eval是再常见不过的手段了,好像任何一本ASP.NET书里都会描述如何把一个DataTable绑定到一个控件里去,并且通过Eval来取值的用法。不过在目前的DDD(Domain Driven Design)时代,我们操作的所操作的经常是领域模型对象。我们可以把任何一个实现了IEnumerable的对象作为绑定控件的数据源,并且在绑定控件中通过Eval来获取字段的值。如下:

protected void Page_Load(object sender, EventArgs e)
{
    List<Comment> comments = GetComments();
    this.rptComments.DataSource = comments;
    this.rptComments.DataBind();
}

<asp:Repeater runat="server" ID="rptComments">
    <ItemTemplate>
        Title: <%# Eval("Title") %>

        Conent: <%# Eval("Content") %>
    </ItemTemplate>
    <SeparatorTemplate>
        <hr />
    </SeparatorTemplate>
</asp:Repeater>
  在这里,Eval对象就会通过反射来获取Title和Content属性的值。于是经常就有人会见到说:“反射,性能多差啊,我可不用!”。在这里我还是对这种追求细枝末节性能的做法持保留态度。当然,在上面的例子里我们的确可以换种写法:

<asp:Repeater runat="server" ID="rptComments">
    <ItemTemplate>
        Title: <%# (Container.DataItem as Comment).Title %>

        Conent: <%# (Container.DataItem as Comment).Content %>
    </ItemTemplate>
    <SeparatorTemplate>
        <hr />
    </SeparatorTemplate>
</asp:Repeater>
  我们通过Container.DataItem来获取当前遍历过程中的数据对象,将其转换成Comment之后读取它的Title和Content属性。虽然表达式有些长,但似乎也是个不错的解决方法。性能嘛……肯定是有所提高了。

  但是,在实际开发过程中,我们并不一定能够如此轻松的将某个特定类型的数据作为数据源,往往需要组合两种对象进行联合显示。例如,我们在显示评论列表时往往还会要显示发表用户的个人信息。由于C# 3.0中已经支持了匿名对象,所以我们可以这样做:

protected void Page_Load(object sender, EventArgs e)
{
    List<Comment> comments = GetComments();
    List<User> users = GetUsers();

    this.rptComments.DataSource = from c in comments
                                  from u in users
                                  where c.UserID == u.UserID
                                  order by c.CreateTime
                                  select new
                                  {
                                      Title = c.Title,
                                      Content = c.Content,
                                      NickName = u.NickName
                                  };
    this.rptComments.DataBind();
}

  我们通过LINQ级联Comment和User数据集,可以轻松地构造出构造出作为数据源的匿名对象集合(有没有看出LINQ的美妙?)。上面的匿名对象将包含Title,Content和NickName几个公有属性,因此在页面中仍旧使用Eval来获取数据,不提。

  不过我几乎可以肯定,又有人要叫了起来:“LINQ没有用!我们不用LINQ!Eval性能差!我们不用Eval!”。好吧,那么我免为其难地为他们用“最踏实”的技术重新实现一遍:

private Dictionary<int, User> m_users;
protected User GetUser(int userId)
{
    return this.m_users[userId];
}

protected void Page_Load(object sender, EventArgs e)
{
    List<Comment> comments = GetComments();
    List<User> users = GetUsers();

    this.m_users = new Dictionary<int, User>();
    foreach (User u in users)
    {
        this.m_users[u.UserID] = u;
    }

    this.rptComments.DataSource = comments;
    this.rptComments.DataBind();
}

<asp:Repeater runat="server" ID="rptComments">
    <ItemTemplate>
        Title: <%# (Container.DataItem as Comment).Title %>

        Conent: <%# (Container.DataItem as Comment).Content %>

        NickName: <%# this.GetUser((Container.DataItem as Comment).UserID).NickName %>
    </ItemTemplate>
    <SeparatorTemplate>
        <hr />
    </SeparatorTemplate>
</asp:Repeater>
嫌反射性能差?算有那么一点道理吧……
  反射速度慢?我同意它是相对慢一些。

  反射占CPU多?我同意他是相对多一点。

  所以Eval不该使用?我不同意——怎能把孩子和脏水一起倒了?我们把反射访问属性的性能问题解决不就行了吗?

  性能差的原因在于Eval使用了反射,解决这类问题的传统方法是使用Emit。但是.NET 3.5中现在已经有了Lambda Expression,我们动态构造一个Lambda Expression之后可以通过它的Compile方法来获得一个委托实例,至于Emit实现中的各种细节已经由.NET框架实现了——这一切还真没有太大难度了。

public class DynamicPropertyAccessor
{
    private Func<object, object> m_getter;

    public DynamicPropertyAccessor(Type type, string propertyName)
        : this(type.GetProperty(propertyName))
    { }

    public DynamicPropertyAccessor(PropertyInfo propertyInfo)
    {
        // target: (object)((({TargetType})instance).{Property})

        // preparing parameter, object type
        ParameterExpression instance = Expression.Parameter(
            typeof(object), "instance");

        // ({TargetType})instance
        Expression instanceCast = Expression.Convert(
            instance, propertyInfo.ReflectedType);

        // (({TargetType})instance).{Property}
        Expression propertyAccess = Expression.Property(
            instanceCast, propertyInfo);

        // (object)((({TargetType})instance).{Property})
        UnaryExpression castPropertyValue = Expression.Convert(
            propertyAccess, typeof(object));

        // Lambda expression
        Expression<Func<object, object>> lambda =
            Expression.Lambda<Func<object, object>>(
                castPropertyValue, instance);

        this.m_getter = lambda.Compile();
    }

    public object GetValue(object o)
    {
        return this.m_getter(o);
    }
}

  在DynamicPropertyAccessor中,我们为一个特定的属性构造一个形为o => object((Class)o).Property的Lambda表达式,它可以被Compile为一个Func<object, object>委托。最终我们可以通过为GetValue方法传入一个Class类型的对象来获取那个指定属性的值。

  这个方法是不是比较眼熟?没错,我在《方法的直接调用,反射调用与……Lambda表达式调用》一文中也使用了类似的做法。

测试一下性能?

  我们来比对一下属性的直接获取值,反射获取值与……Lambda表达式获取值三种方式之间的性能。

var t = new Temp { Value = null };

PropertyInfo propertyInfo = t.GetType().GetProperty("Value");
Stopwatch watch1 = new Stopwatch();
watch1.Start();
for (var i = 0; i < 1000000; i ++)
{
    var value = propertyInfo.GetValue(t, null);
}
watch1.Stop();
Console.WriteLine("Reflection: " + watch1.Elapsed);

DynamicPropertyAccessor property = new DynamicPropertyAccessor(t.GetType(), "Value");
Stopwatch watch2 = new Stopwatch();
watch2.Start();
for (var i = 0; i < 1000000; i++)
{
    var value = property.GetValue(t);
}
watch2.Stop();
Console.WriteLine("Lambda: " + watch2.Elapsed);

Stopwatch watch3 = new Stopwatch();
watch3.Start();
for (var i = 0; i < 1000000; i++)
{
    var value = t.Value;
}
watch3.Stop();
Console.WriteLine("Direct: " + watch3.Elapsed);

  结果如下:

Reflection: 00:00:04.2695397
Lambda: 00:00:00.0445277
Direct: 00:00:00.0175414
  使用了DynamicPropertyAccessor之后,性能虽比直接调用略慢,也已经有百倍的差距了。更值得一提的是,DynamicPropertyAccessor还支持对于匿名对象的属性的取值。这意味着,我们的Eval方法完全可以依托在DynamicPropertyAccessor之上。

离快速Eval只有一步之遥了
  “一步之遥”?没错,那就是缓存。调用一个DynamicPropertyAccessor的GetValue方法很省时,可是构造一个DynamicPropertyAccessor对象却非常耗时。因此我们需要对DynamicPropertyAccessor对象进行缓存,如下:

public class DynamicPropertyAccessorCache
{
    private object m_mutex = new object();
    private Dictionary<Type, Dictionary<string, DynamicPropertyAccessor>> m_cache =
        new Dictionary<Type, Dictionary<string, DynamicPropertyAccessor>>();

    public DynamicPropertyAccessor GetAccessor(Type type, string propertyName)
    {
        DynamicPropertyAccessor accessor;
        Dictionary<string, DynamicPropertyAccessor> typeCache;

        if (this.m_cache.TryGetValue(type, out typeCache))
        {
            if (typeCache.TryGetValue(propertyName, out accessor))
            {
                return accessor;
            }
        }

        lock (m_mutex)
        {
            if (!this.m_cache.ContainsKey(type))
            {
                this.m_cache[type] = new Dictionary<string, DynamicPropertyAccessor>();
            }

            accessor = new DynamicPropertyAccessor(type, propertyName);
            this.m_cache[type][propertyName] = accessor;

            return accessor;
        }
    }
}

  经过测试之后发现,由于每次都要从缓存中获取DynamicPropertyAccessor对象,调用性能有所下降,但是依旧比反射调用要快几十上百倍。

FastEval——还有人会拒绝吗?
  FastEval方法,如果在之前的.NET版本中,我们可以将其定义在每个页面的共同基类里。不过既然我们在用.NET 3.5,我们可以使用Extension Method这种没有任何侵入的方式来实现:

public static class FastEvalExtensions
{
    private static DynamicPropertyAccessorCache s_cache =
        new DynamicPropertyAccessorCache();

    public static object FastEval(this Control control, object o, string propertyName)
    {
        return s_cache.GetAccessor(o.GetType(), propertyName).GetValue(o);
    }

    public static object FastEval(this TemplateControl control, string propertyName)
    {
        return control.FastEval(control.Page.GetDataItem(), propertyName);
    }
}

  我们在Control上的扩展,确保了每个页面中都可以直接通过一个对象和属性名获取一个值。而在TemplateControl上的扩展,则使得各类可以绑定控件或页面(Page,MasterPage,UserControl)都可以直接通过属性名来获取当前正在绑定的那个数据对象里的属性值。

  现在,您还有什么理由拒绝FastEval?

其他
  其实我们整篇文章都小看了Eval方法的作用。Eval方法的字符串参数名为“expression”,也就是表达式。事实上我们甚至可以使用“.”来分割字符串以获取一个对象深层次的属性,例如<%# Eval("Content.Length") %>。那么我们的FastEval可以做到这一点吗?当然可以——只不过这需要您自己来实现了。:)

  最后再留一个问题供大家思考:现在DynamicPropertyAccessor只提供一个GetValue方法,那么您能否为其添加一个SetValue方法来设置这个属性呢?希望大家踊跃回复,稍后我将提供我的做法。

思考题解答
  有一点大家应该知道,一个属性其实是由一对get/set方法组成(当然可能缺少其中一个)。而获取了一个属性的PropertyInfo对象之后,可以通过它的GetSetMethod方法来获取它的设置方法。接下来的工作,不就可以完全交给《方法的直接调用,反射调用与……Lambda表达式调用》一文里的DynamicMethodExecutor了吗?因此为DynamicPropertyAccessor添加一个SetValue方法也很简单:

public class DynamicPropertyAccessor
{
    ...
    private DynamicMethodExecutor m_dynamicSetter;

    ...

    public DynamicPropertyAccessor(PropertyInfo propertyInfo)
    {
        ...

        MethodInfo setMethod = propertyInfo.GetSetMethod();
        if (setMethod != null)
        {
            this.m_dynamicSetter = new DynamicMethodExecutor(setMethod);
        }
    }

    ...

    public void SetValue(object o, object value)
    {
        if (this.m_dynamicSetter == null)
        {
            throw new NotSupportedException("Cannot set the property.");
        }

        this.m_dynamicSetter.Execute(o, new object[] { value });
    }
}

使用 MATLAB/Simulink + Deep Learning Toolbox,构建一个基于LSTM的电网负荷预测模 本文介绍了一个基于Simulink和深度学习的智能电网负荷预测与调度建模方法。通过LSTM神经网络构建负荷预测模型,将历史负荷、天气、日期等特征作为输入,预测未来24小时负荷。然后将训练好的模型集成到Simulink仿真系统中,结合发电单元模型和经济调度逻辑,实现预测驱动的电力调度优化。实验结果表明,该方法预测误差在2.5%-4.0%之间,相比传统调度方式可降低15%-25%的运行成本。文章详细展示了从数据准备、特征工程、模型训练到系统集成的完整流程,为智能电网中AI技术的应用提供了实用参考。 阅读详情

相关推荐

apm软件仿真+QGC地面站 环境搭建

本教程使用场景:apm软件仿真运行于虚拟机 ubuntu环境。qgc地面站位于windows 系统。两个环境在同一台电脑上。 一.apm仿真环境搭建 1.安装vm虚拟机及ubuntu 18。 2.ubuntu下 下载Ardupilot 飞控源码 并配置环境。 下载源码: git clone https://github.com/ArduPilot/ardupilot cd ardupilot git submodule update --init --recursive 配置所需运行的环境:

qthello 6110

详解Java执行groovy脚本的两种方式

Java// 初始化Bindings// 绑定参数// 定义groovy脚本中执行方法的名称// 定义groovy脚本内容" +" +" +"}";try {// 执行脚本// 获取执行结果try {// 初始化groovy脚本对象// 定义groovy脚本中执行方法的名称// 定义参数// 执行脚本并获取结果。

LuckFairyLuckBaby的博客 1555

DTS 数据迁移

支持关系型数据库(MySQL, Oracle, SQL Server等)、NoSQL数据库、大数据系统等。DTS数据迁移是现代化数据架构调整和云迁移过程中的重要工具,能够大大降低数据迁移的复杂度和风险。DTS (Data Transmission Service) 是一种数据迁移和同步服务,:先迁移历史数据(全量),再实时同步新增变化(增量):不同数据库类型间迁移,如Oracle到MySQL。:将单库数据迁移到分库分表架构。:将业务数据迁移到分析型数据库。:将本地数据库迁移到云数据库。

qq_41081716的博客 749

Groovy常用语法总结

过去半年都在写Groovy,基本都是在实战中学习,从java转过来,也还没什么问题,毕竟基础,架构都没变。 Groovy的强大特性中,Closure,MetaClass都尝试过,Closure基本上就是当方法或者回调接口使用,再高级的用法就没用过了,没有特别体会什么好处,当回调接口就是省的定义接口,简洁了一些;MetaClass就有专门为一个模块做了些MetaClass,和GORM差不多的,给一...

云计算? 508

青藏高原冻土数据实战:如何用QGIS分析1961-2020年冻土退化趋势(附完整操作步骤)

本文详细介绍了如何使用QGIS分析1961-2020年青藏高原冻土退化趋势,包括数据准备、预处理、时空分析和模型验证等全流程操作。通过TTOP模型和Stefan方程,揭示了冻土退化的空间差异和海拔依赖性,为环境研究提供科学依据。

weixin_29276847的博客 127

信号完整性仿真SI之Cadence Sigrity SPEED2000_眼图仿真(四)

今天给大家分享一个仿真的操作流程,是关于Cadence Sigrity SPEED2000的时域波形仿真和眼图仿真。我们会经常看见硬件工程师调试示波器上的一些信号的波形变化,其实这些也可以通过仿真电路的搭建来做出投板前的仿真,来优化走线,以减少版本的迭代次数。如果要和实际的信号保持一致,就要求仿真设置的参数和实际的参数保持一致,这也是仿真的重点和难点。下面先让我们了解一下Cadence Sigrity SPEED2000时域仿真的操作流程: 1.仿真模式选择与文件导入 选择Cadence Sigrity下的

刘小同学的博客 1万+

使用Groovy脚本引擎 根据表达式求值 或 反向解析构造对象

假设有这么一个需求:外部传入一个Map形式的字符串,如"[1:A,2:B]",现在要把这个字符串转换成map对象。 如果自己去解析并构造出map对象,显然很麻烦。 Groovy可以执行脚本,将一个脚本字符串传给GroovyShell,它再去sh.evaluate(expression). 所有我们也可以利用它来帮我们解析出map对象。 Map map = new Groo

谢炜的专栏 3435

从“破解”到应用:三菱数控系统M80协议逆向分析与工业数据采集网关搭建指南

本文深入解析三菱数控系统M80协议的逆向分析方法与工业数据采集网关搭建技术。通过TCP协议实现跨平台通信,详细介绍了M80协议的数据包结构、多语言实现方案(C#、Java、C/C++)以及Linux数据采集网关的架构设计与容器化部署。为工业自动化领域的开发者提供从协议分析到企业级数据采集落地的完整解决方案。

weixin_29228781的博客 1212

Groovy学习笔记

Groovy学习笔记

biubiubiubibibi的博客 797

ESP32 驱动 SYN6288 语音合成:Arduino IDE 下实现中文数字混合文本的智能播报

本文详细介绍了如何在Arduino IDE环境下使用ESP32驱动SYN6288语音合成模块,实现中文数字混合文本的智能播报。通过硬件选型、开发环境搭建、编码转换原理、命令帧构造及串口通信实战等步骤,帮助开发者快速掌握语音播报技术。文章还提供了混合文本处理技巧和常见问题排查方法,适合智能硬件开发者参考。

weixin_42553471的博客 448

GaussDB本地安装手册(主备模式)

如果实例状态是Normal,则安装成功。三节点集中式配置文件。

Sebastien23的博客 2633

这下没理由嫌Eval的性能差了吧?

Updated:提供思考题解答 好吧,你偏要说Eval性能差 写ASP.NET中使用Eval是再常见不过的手段了,好像任何一本ASP.NET书里都会描述如何把一个DataTable绑定到一个控件里去,并且通过Eval来取值的用法。不过在目前的DDD(Domain Driven Design...

chuifuhuo6864的博客 179

RT-DETR改进前必看 - Ultralytics调参 1:1还原RT-DETR官方版本实验环境,更方便改进

的项目文件中集成了YOLOv3v5v6v8v9v10rt-detr11以及其中不同大小的模型结构,更方便我们学习和使用。的参数配置在路径下,其中中设置了模型在训练Train验证Val/Test预测Predict可视化Visualize导出Export超参数Hyperparameters、以及跟踪Tracker的相关参数。在调参过程中主要涉及训练Train和超参数Hyperparameters。下面主要介绍一下初始超参数Hyperparameters。

Limiiiing的博客 7960

Asp.net Eval 学习总结

C# Eval在asp.net中的用法及作用 https://www.cnblogs.com/Mr_JinRui/archive/2010/07/06/1772129.html Eval( " ")和Bind( " ") 这两种一个单向绑定,一个双向绑定,bind是双向绑定,但需数据源支持 ASP.NET 2.0改善了模板中的数据绑定操作,把v1.x中的数据绑定语法DataBinder.E...

bcbobo21cn的专栏 1891

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

asp.net bind()和eval()的区别

eval()方法 在运行时使用反射执行后期绑定计算,因此与标准的ASP.NET数据绑定方法bind相比,会导致性能明显下降。它一般用在绑定时需要格式化字符串的情况下。多数情况尽量少用此方法 Eval 方法是静态(只读)方法,该方法采用数据字段的值作为参数并将其作为字符串返回。Bind 方法支持读/写功能,可以检索数据绑定控件的值并将任何更改提交回数据库。 使用 Eval 方法 Eval 方

mailangel123的专栏 507

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

Bind和Eval的不同用法 (asp.net C#)

今天在用DataList的模板列的时候习惯性地像在03中那样去给模板列的绑定字段加个处理函数:asp:Label ID="Label1" runat="server" Text=>asp:Label>     可是竟然出错:当前上下文中不存在名称“Bind” 。         后来又习

bentonite的专栏 1254

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

mysql类似eval的函数_替代Eval的两种方式

在asp.net中的数据绑定中,我们经常会用到Eval,不过大家都知道Eval绑定是通过反射来实现的, 而反射势必会对性能造成一定的影响。不过有两种替代的方式来实现绑定数据,对性能略有提高。1 当数据源为DataTable时,用下面的方式:后台代码protected void Page_Load(object sender, EventArgs e){DataTable dt = new Data...

weixin_39624429的博客 436

ASP.NET中的Eval()和DataBinder.Eval()方法

<span style="font-family: function() { var id = (this._style >> 24) & 0xff; color: #000000; font-size: medium;">ASP.NET中的Eval()和DataBinder.Eval()方法Eval( " ")和Bind( " ") 这两种一个单向绑定,一个双向绑定 bind是双向绑

熊小屁的专栏 535

Asp.net中Bind和Eval的区别详细说明

eval()方法在运行时使用反射执行后期绑定计算,因此与标准的ASP.NET数据绑定方法bind相比,会导致性能明显下降。它一般用在绑定时需要格式化字符串的情况下。多数情况尽量少用此方法 Eval 方法是静态(只读)方法,该方法采用数据字段的值作为参数并将其作为字符

Finder_Way 441

Asp.Net的Eval数据绑定

<%# DataBinder.Eval(Container.DataItem,"xxxx")%> 或 <%# Eval("xxxx")%> <%# DataBinder.Eval(Container,"DataItem.xxxx")%> <%# ((DataRowView)Container.DataItem)["xxxx"]%> AS...

weixin_30716141的博客 74

引用 ASP.NET中的Eval()和DataBinder.Eval()方法

悠闲的自我 的 ASP.NET中的Eval()和DataBinder.Eval()方法<br /><br />Eval( " ")和Bind( " ") 这两种一个单向绑定,一个双向绑定<br />bind是双向绑定,但需数据源可更改才能用<br />ASP.NET 2.0改善了模板中的数据绑定操作,把v1.x中的数据绑定语法DataBinder.Eval(Container.DataItem, fieldname)简化为Eval(fieldname)。Eval方法与DataBinder.Eval一样可以接

jinjiangdongfang的专栏 544

.NET中Bind和Eval的区别

eval()方法在运行时使用反射执行后期绑定计算,因此与标准的asp.net数据绑定方法bind相比,会导致性能明显下降。它一般用在绑定时需要格式化字符串的情况下。多数情况尽量少用此方法   Eval 方法是静态(只读)方法,该方法采用数据字段的值作为参数并将其作为字符串返回。Bind 方法支持读/写功能,可以检索数据绑定控件的值并将任何更改提交回数据库。   asp.net中的Bind和Eval:使用 Eval 方法   Eval 方法可计算数据绑定控件(如 GridView、Detai

xueer8835的专栏 3338

“.NET研究”ASP.NET绑定的技巧

Data Binding似乎是ASP.NET老掉牙的节目,无非Eval之流。其实稍作加工就能使其脱胎换骨。 在代码中加入: //推荐放在基类 protected virtual object ExpHelper&lt;TEntity, TREsult&gt;(Func&lt;TEntity, TREsult&gt; func) { var itm = GetDataItem(); ...

weixin_34415923的博客 90

ASP.NET中的DataBinder.Eval用法

# Bind("Subject") %> //绑定字段# Container.DataItemIndex + 1%> //实现自动编号# DataBinder.Eval(Container.DataItem, "[n]") %> 通常使用的方法# DataBinder.Eval(Container.DataItem, "ColumnName") %> # DataBinder.Eval(Conta

3501
上一篇: ASP.NET 2.0的Eval方法揭秘
下一篇: asp.net 2.0取消页面缓存
UniMagic
博客等级 码龄20年 24粉丝 40原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

UniMagic

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值