Skip to content

About

TypeCmpAndCloneGenerator for pure C# version

Resources

Stars

1 star

Watchers

1 watching

Forks

Latest commit

 

History

18 Commits

Folders and files

Repository files navigation

版本更新日志

2021.8.6 最初的版本。目前存在的问题:

  1. 有field为class的时候,没有判空。(当然,作为Unity序列化数据的使用是没有问题的)
  2. 当存在一个field,继承自List的时候,不会被认为是数组类型的,后面应当使用类似于Odin中TypeExtension中判断一个类型是否继承自List的做法来实现数组类型的相关操作。
  3. 有些ILEmit中代码太长了,应当抽取常用部分,构建面向对象的IL编程。
  4. 关于Clone方法,后面需要想办法使得第一个参数带ref,使得更方便的使用,否则,参数中带有null的一些情况可能不能令人满意。但是测试一下发现lambda中参数似乎不能用ref修饰。后面可能需要考虑类似于在Clone方法的参数中带一个上带一个父类上下文,来避免这个问题。(2021.8.14已解决)

2021.8.8 更新如下:

  1. 检查了field为class的情况下,有null存在的情况。
  2. 对il提供了一些便利的扩展(例如if-then-else块等等),后续需要扩展更多常用的语句,并重构以前的代码结构。
  3. 新问题:在处理class为null的情况突然发现,解析数组类型的时候,只考虑了作为field存在的时候,没有考虑来源也为数组的时候,例如List<List>。(总结一下,只要当前域可能为null,就要处理三种情况的来源,作为顶层参数,作为常规field,作为数组的item)
  4. 新问题:发现没有处理field为高维数组的情况。

2021.8.14 更新如下:

  1. 修复了List中T一些类型在new的时候考虑漏的情况。
  2. 引入了一个据说是来自于Orleans框架深拷贝的DeepCopy源码(https://github.com/ReubenBond/DeepCopy ),想到了第一个参数不能带ref的解决方案,利用 a = clone(b); 来保证值能被正确带出,但是一直new可能性能会欠佳,因此考虑 a = clone(a, b); 的形式,将a传入,避免a本身不为null的情况也被new一次,来提升效率。 大致测试了一下性能以后发现这种优化速度可以提升10倍左右,非常nice!
  3. 新问题:发现没有处理Dictionary相关的深拷贝。

2021.8.20 更新如下:

  1. 修复了深拷贝时struct的class处理不正确的情况,加载域应当使用ldflda而不是ldfld。

2021.8.23 更新如下:

  1. 需要注意的是当struct作为class的域被直接用等号赋值的时候,使用ldfld;当对struct的域进行赋值时,加载struct必须使用ldflda。

2022.9.24 更新如下:

  1. 修复了 a = clone(b) 形式的拷贝在最顶层直接赋值时由于参数错误会报错的情况

新问题:

  1. 发现拷贝失效的类:Unity的AnimationCurve(本质是没处理property的情况)(2022.9.25已解决)

2022.9.25 更新如下:

  1. 实现了对property的拷贝处理
  2. 修复了T[]类型的一些bug
  3. 修复了对struct数组的item的字段进行赋值时的bug,例如 List<Vector3> list, 使用 list[i].x = val 的情况,应当忽略字段,直接复制整个struct,如 list[i] = target[i](这是错误的,见2022.10.4)
  4. 修复了部分Unity类型下T[]类型字段的拷贝问题,原因在于Unity对外的数组一般使用property的形式进行处理,并且返回一份拷贝,导致T[]字段在设置item时失效(例如AnimationCurve的keys,类型为Keyframe[])(现在的处理方式是将Unity类型下的T[]字段直接传递,即a.keys = b.keys)

新问题:

  1. 考虑到对递归类型是逐一获取子字段来生成代码,在面对 A 字段中含有 List 的情形,在生成方法时就会由于递归直接死循环,应该采用对相同类型采用Cache的做法(但是如何处理例如链表形式的A中直接带有A呢?可能需要ForwardDeclare之类的处理方式)(2022.10.4已解决)
  2. 深比较中没有进行对property的处理,可能会导致cmp和clone不一致的情况(2022.10.4已解决)
  3. 基于更新的第4点,处理流程需要优化,最后的流程应该为:先从原数组中获取拷贝,从目标数组中进行内容复制,最后将拷贝返还给原数组。(2022.10.6已解决)

2022.10.2 更新如下:

  1. 修复了List<T>类型添加一个默认项的时候,UnityEngine.Object类型的默认创建为null(其实都可以这么做,全部默认为null即可,传递到item的时候item那边自己会处理的)
  2. 本地添加了一个单元测试,准备开始重构

新问题:

  1. Clone的时候,引用同一个数据的地方,在新生成的数据中也理应保持同样的结构,这部分可以参照DeepCopy中的做法,直接搞一个表记录一下即可。

2022.10.4 更新如下:

  1. 利用泛型类,在类中存储了类型所需的cmp和clone函数,省去了查表和将object转成对应Action或者Func类型的时间
  2. 增加了对递归类型的处理,大致上参考了DeepCopy中的做法,但也保留了部分函数展开的做法;简单来说,对一个类型,如果检查到可能类型递归了以后,让il调用事先存储的该类的对应方法,使得运行时去处理,否则,还是按照之前函数展开的形式;这样可以让性能达到极致,总体的性能仍然是优于DeepCopy不少的;目前看来对于string的拷贝较慢,待查。
  3. 深比较中添加了对property的处理
  4. 修复struct拷贝时的错误,原因是2022.9.25更新时引发的错误,目前的处理方案是当一个struct type上层为List时,采取浅拷贝直接复制整个struct(这是错误的),否则仍然采取深拷贝的处理;后边把这个再处理完善一些。(2022.10.5已修复)

2022.10.5 更新如下:

  1. 修复List下Item Clone的Bug,不论是struct还是class统一采取先拷贝item,再利用list.set(i, item)的方式赋值
  2. 解决string拷贝性能的问题(原因是无参构造器的类型调用GetUninitializedObject开销还是挺高的)

2022.10.6 更新如下:

  1. 优化了T[]的拷贝流程:目前统一为从来源get数组,执行操作后,最后set回去。这样对T[]的property处理比较友好。
  2. 修复了2022.10.5对List Item Clone重构后的种种bug。
  3. 修复了部分struct加载的bug:重申一下2021.8.23的描述,struct作为整体使用(如整体比较),使用ldfld;需要加载某个域,使用ldflda,需要取地址。

2022.10.30 更新如下:

  1. 支持了对数组中多态item的拷贝(多态数组的cmp尚未支持)
  2. 修复了部分struct加载的bug:整体拷贝或者整体返回使用时候没有使用取地址操作符的bug。

新问题:

  1. 多态数组拷贝时,如果使用listA = clone(listA, listB)的形式,前后某一项的类型不相同,应该如何处理?可能应该强制遵循后者类型。

About

TypeCmpAndCloneGenerator for pure C# version

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages