编程开源技术交流,分享技术与知识

网站首页 > 开源技术 正文

0x01 - 我的第一个 Object Visitor

wxchong 2024-07-22 23:01:43 开源技术 10 ℃ 0 评论

我的第一个 Object Visitor

预演准备

为了顺利的进行测试,你需要确保本地已经安装了以下这些必备的软件:

  • dotnet 2.1 或者以上版本的 SDK,我们更建议直接安装 dotnet 5 SDK。下载地址:https://dotnet.microsoft.com/download
  • 安装一个趁手的 .net IDE。本演示过程将会使用 Visual Studio Code 作为基础演示 IDE。你也可以选择 Rider 或者 Visual Studio 来完成。

创建测试项目

我们需要一个测试项目来演示如何创建一个属于你的第一个 Object Visitor。

首先,确保本地已经正确安装了 dotnet 2.1 或者以上版本的 sdk,你可以运行以下命令来确认当前安装的版本:

dotnet --info

然后,随便找一个你喜欢的文件夹,运行以下命令来创建用于演示的测试控制台程序:

dotnet new console

最后,继续运行以下命令来安装最新的 Newbe.ObjectVisitor 工具包:

dotnet add package newbe.objectvisitor

这样,用于测试的项目就创建完成了。

创建一个简单的数据模型

我们使用 IDE 打开刚刚创建的项目,添加一个简单的数据模型类 OrderInfo :

public class OrderInfo
{
    public int OrderId { get; set; }
    public string Buyer { get; set; }
    public decimal TotalPrice { get; set; }
}

实现一个拼接所有属性的逻辑

我们在 Program.cs 中添加以下代码来完成这些逻辑:

  1. new 一个 OrderInfo order
  2. 使用 StringBuilderorder 的所有属性名称和值拼接在一起
  3. 输出最后的 string
using System;
using System.Text;

namespace yueluo_dalao_yes
{
    class Program
    {
        static void Main(string[] args)
        {
            var order = new OrderInfo
            {
                OrderId = 1,
                Buyer = "yueluo",
                TotalPrice = 62359.1478M
            };
            var sb = new StringBuilder();
            sb.AppendFormat("{0}: {1}{2}", nameof(order.OrderId), order.OrderId, Environment.NewLine);
            sb.AppendFormat("{0}: {1}{2}", nameof(order.Buyer), order.Buyer, Environment.NewLine);
            sb.AppendFormat("{0}: {1}{2}", nameof(order.TotalPrice), order.TotalPrice, Environment.NewLine);
            Console.WriteLine(sb.ToString());
        }
    }

    public class OrderInfo
    {
        public int OrderId { get; set; }
        public string Buyer { get; set; }
        public decimal TotalPrice { get; set; }
    }
}

我们使用以下命令来运行写好的逻辑:

dotnet run

就会得到以下这样的结果:

OrderId: 1
Buyer: yueluo
TotalPrice: 62359.1478

使用 Object Visitor 再次实现上面的逻辑

我们通过 Newbe.ObjectVisitor 来一样实现上面的逻辑:

  1. 使用 V() 扩展方法来创建一个 Object Visitor
  2. 调用 Object Visitor 的 ForEach 方法来注册 Visit 过程的行为
  3. 运行创建好的 Object Visitor
using System;
using System.Text;

namespace yueluo_dalao_yes
{
    class Program
    {
        static void Main(string[] args)
        {
            var order = new OrderInfo
            {
                OrderId = 1,
                Buyer = "yueluo",
                TotalPrice = 62359.1478M
            };

            var sb2 = new StringBuilder();
            var visitor = order.V()
                .ForEach((name, value) => sb2.AppendFormat("{0}: {1}{2}", name, value, Environment.NewLine));
            visitor.Run();
            Console.WriteLine(sb2.ToString());
        }
    }

    public class OrderInfo
    {
        public int OrderId { get; set; }
        public string Buyer { get; set; }
        public decimal TotalPrice { get; set; }
    }
}

运行这个代码,你将会得到和上一节相同的结果。

那这么做究竟带来了什么好处?

首先,使用 Object Visitor 可以动态的适应模型类的变化,这点好处非常明显。

OrderInfo 中的属性增加时,“拼接部分” 的代码可以不用变化,实现动态的适配。

另外,还有一些好处是本示例没有体现的,将会在后续的文档中进行介绍:

  1. 它的运行效率很高。根据已有的基准测试,其性能表征和直接硬编码差距很小。
  2. 可以使用丰富的方式来对需要访问的属性进行多种方式过滤,例如:基于 Attribute 的过滤。
  3. 有了这种方式之后可以很轻松的扩展出基于对象属性的其他功能,例如:对象的属性验证(FluentValidation),对象的映射(AutoMapper)和对象的比较(Comparer)。

那这和直接使用反射有什么区别?

使用反射来实现以上的效果也是可以的,但相较来说,Object Visitor 的实现方式在性能方面根据优势:

  1. 根据已有的基准测试,Object Visitor 基于表达式树实现,其运行效率要比直接使用反射相关的读写方法高出许多。
  2. Object Visitor 提供了基于泛型,在一些特定的场景可以完全避免装箱拆箱所带来的开销。

你可以通过点击这里来查看使用反射和使用 object visitor 的基准测试

本篇小结

到这里,你已经初步了解了什么是 Newbe.ObjectVisitor,以及其基本的用法。

不过,这只是演示代码,展现的内容非常有限,因此,你还可以继续阅读下篇来进一步了解更多紧张刺激的特性。

发布说明

  • Newbe.ObjectVisitor 0.4.4 发布,模型验证器上线
  • Newbe.ObjectVisitor 0.3.7 发布,自动生成 FluentAPI
  • Newbe.ObjectVisitor 0.2.10 发布,更花里胡哨
  • Newbe.ObjectVisitor 0.1.4 发布,初始版本

使用样例

  • Newbe.ObjectVisitor 样例 1
  • 0x01 - 我的第一个 Object Visitor
  • 0x02 - 创建并缓存 Object Visitor
  • 0x03-ForEach 全面观
  • 0x04 - 过滤属性
  • 0x05 - 综合示例,导出 CSV

开发文档可能随版本发生变化,查看最新的开发文档需移步 http://cn.ov.newbe.pro

番外分享

  • 寻找性能更优秀的动态 Getter 和 Setter 方案
  • 寻找性能更优秀的不可变小字典
  • 我画着图,FluentAPI 她自己就生成了

GitHub 项目地址:https://github.com/newbe36524/Newbe.ObjectVisitor

Gitee 项目地址:https://gitee.com/yks/Newbe.ObjectVisitor

相关文章

  • 只要十步,你就可以应用表达式树来优化动态调用
  • 0x02 - 创建并缓存 Object Visitor
  • 0x03-ForEach 全面观
  • 0x04 - 过滤属性
  • 0x05 - 综合示例,导出 CSV


------ 本文结束 ------

  • 本文作者: newbe36524
  • 本文链接: https://www.newbe.pro/Newbe.ObjectVisitor/001-my-fisrt-object-visitor/
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表