有效的方式来克隆的HashSet< T>? [英] Efficient way to clone a HashSet<T>?

查看:304
本文介绍了有效的方式来克隆的HashSet< T>?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

前几天,我回答一个有趣的问题上SO约的HashSet< T> 。一个可能的解决方案涉及克隆HashSet的,在我的答案,我建议做这样的事情:

A few days ago, I answered an interesting question on SO about HashSet<T>. A possible solution involved cloning the hashset, and in my answer I suggested to do something like this:

HashSet<int> original = ...
HashSet<int> clone = new HashSet<int>(original);

虽然这种方法是相当简单的,我怀疑这是非常低效:的构造新的的HashSet&LT; T&GT; 需要分别从原来的HashSet中添加每个项目, 检查,如果尚未present 。这显然​​是在浪费时间:因为源集合是一个的ISet&LT; T&GT; ,这是保证不包含重复。应该有一种方法来充分利用这些知识...

Although this approach is quite straightforward, I suspect it's very inefficient: the constructor of the new HashSet<T> needs to separately add each item from the original hashset, and check if it isn't already present. This is clearly a waste of time: since the source collection is a ISet<T>, it is guaranteed not to contain duplicates. There should be a way to take advantage of that knowledge...

在理想情况下,的HashSet&LT; T&GT; 应实施 ICloneable ,但不幸的是它并非如此。我还检查了反射,看看是否的HashSet&LT; T&GT; 构造做了具体的,如果源收集是HashSet的东西,但事实并非如此。这也许可以通过使用反射私人领域来完成,但是这将是一个丑陋的黑客攻击...

Ideally, HashSet<T> should implement ICloneable, but unfortunately it's not the case. I also checked with Reflector to see if the HashSet<T> constructor did something specific if the source collection was a hashset, but it doesn't. It could probably be done by using reflection on private fields, but that would be an ugly hack...

所以,也有人想出了一个聪明的解决方案,以更有效地克隆HashSet的?

(注意,这个问题是纯理论的,我也不需要做,在一个真正的程序)

(Note that this question is purely theoretical, I don't need to do that in a real program)

推荐答案

如果你真的想克隆一个 HashSet的&LT的最有效方式; T&GT; ,你会怎么做以下(但可能在可维护性的费用)

If you really wanted the most efficient way to clone a HashSet<T>, you'd do the following (but possibly at the cost of maintainability)

  1. 使用反射器或调试器来找出到底是什么在 HashSet的&LT领域; T&GT; 需要被复制。您可能需要做递归地为每个字段。
  2. 使用 Reflection.Emit的或使用前pression树木来这做的所有字段的必要复制的方法。可能需要调用哪个拷贝每一个字段的值其他生成的方法。我们正在使用运行时code一代,因为它是直接访问私有字段的唯一途径。
  3. 使用 FormatterServices.GetUninitializedObject(...)来实例化一个空白的对象。使用在步骤2中产生的方法对原始对象复制到新的空白对象。
  1. Use reflector or the debugger to figure out exactly what fields in HashSet<T> need to be copied. You may need to do this recursively for each field.
  2. Use Reflection.Emit or use expression trees to generate a method which does the necessary copying of all of the fields. May need to call other generated methods which copy the value of each field. We're using runtime code generation because it's the only way to directly access private fields.
  3. Use FormatterServices.GetUninitializedObject(...) to instantiate a blank object. Use the method generated in step 2 to copy the original object to the new blank object.

这篇关于有效的方式来克隆的HashSet&LT; T&GT;?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆