冲压/标记/品牌对象实例 [英] Stamping / Tagging / Branding Object Instances

查看:174
本文介绍了冲压/标记/品牌对象实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有,它接受一个对象,做一些关于它的处理程序。该物体可能会或可能,不是可变的。

I have a routine which accepts an object and does some processing on it. The objects may or may-not be mutable.

void CommandProcessor(ICommand command) {
    // do a lot of things
}

有是,同样的命令实例循环回到处理器中的概率。物转讨厌当这种情况发生。我要检测这些游客返回和$ P $被处理pvent他们。问题是我怎么能做到这一点透明即不影响对象本身。

There is a probability that the same command instance loops back in the processor. Things turn nasty when that happens. I want to detect these return visitors and prevent them from being processed. question is how can I do that transparently i.e. without disturbing the object themselves.

这是我试过

  • 添加属性布尔访问{获取,设置} 的ICommand

我不喜欢这样,因为一个模块的逻辑出现在其他。该 shutdown命令涉及关停,不能与簿记。另外一个 EatIceCreamCommand 可随时返回在希望得到更多。一些非可变对象有直接的问题,一个引领者。

I dont like this because the logic of one module shows up in other. The ShutdownCommand is concerned with shutting down, not with the bookkeeping. Also an EatIceCreamCommand may always return False in a hope to get more. Some non-mutable objects have outright problems with a setter.

  • 在私下维护所有处理情况的查询表。当一个对象来对列表中第一次检查。

我不喜欢这样无论是。 (1)性能。查找表变大。我们需要做的内胆搜索相匹配的实例。 (2)不能依赖于散code 。该对象可以伪造一个不同的哈希code不时。 (3)保持的对象列表中的$ P $被垃圾收集pvents他们。

I dont like this either. (1) performance. the lookup table grows large. we need to do liner search to match instances. (2) cant rely on hashcode. the object may forge a different hashcode from time to time. (3) keeping the objects in a list prevents them from being garbage collected.

我需要一种方法来将一些看不见的标记上的实例(的ICommand的)的 的这只是我的code可以看到。目前我没有在调用之间的区别。只是祈祷相同的情况下,不回来了。没有任何人有一个更好的主意来实现这个功能..?

I need a way to put some invisible marker on the instance (of ICommand) which only my code can see. currently i dont discriminate between the invocations. just pray the same instances dont come back. does anyone have a better idea to implement this functionality..?

推荐答案

假设你不能发生只是逻辑上制止这种(尝试切出环)我会去一个的HashSet 。

Assuming you can't stop this from happening just logically (try to cut out the loop) I would go for a HashSet of commands that you've already seen.

即使对象是违反哈希code 和合约等于(我会查看作为一个问题开始),你可以创建自己的的IEqualityComparer< ICommand的> ,它使用的 System.Runtime.CompilerServices.RuntimeHelpers.GetHash code Object.GetHash code 非虚拟化。该等于的方法也只是测试的参考身份。因此,您的池将包含而不关心是否或如何命令重写不同的情况下,等于 GetHash code

Even if the objects are violating the contracts of HashCode and Equals (which I would view as a problem to start with) you can create your own IEqualityComparer<ICommand> which uses System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode to call Object.GetHashCode non-virtually. The Equals method would just test for reference identity. So your pool would contain distinct instances without caring whether or how the commands override Equals and GetHashCode.

这只是叶积累的垃圾问题。假设你没有定期清洗水池的选项,你可以使用 的WeakReference&LT; T&GT; (或者非泛型的WeakReference 类.NET 4)避免固定物体。然后你会发现所有的死弱引用每隔一段时间到prevent甚至累积的。 (你的比较器实际上是一个的IEqualityComparer&LT; WeakReference的&LT; T&GT;&GT; 在这种情况下,比较的目标身份的弱引用的)

That just leaves the problem of accumulating garbage. Assuming you don't have the option of purging the pool periodically, you could use WeakReference<T> (or the non-generic WeakReference class for .NET 4) to avoid retaining objects. You would then find all "dead" weak references every so often to prevent even accumulating those. (Your comparer would actually be an IEqualityComparer<WeakReference<T>> in this case, comparing the targets of the weak references for identity.)

这不是尤其的优雅,但我认为这是固有的设计 - 你需要处理命令某处改变状态,并通过定义一个不可变对象不能改变状态,所以你需要的命令之外的状态。哈希集似乎是一个相当合理的做法,并希望我已经说得很清楚,你如何能避免所有三个你所提到的。

It's not particularly elegant, but I'd argue that's inherent in the design - you need processing a command to change state somewhere, and an immutable object can't change state by definition, so you need the state outside the command. A hash set seems a fairly reasonable approach for that, and hopefully I've made it clear how you can avoid all three of the problems you mentioned.

编辑:我没有考虑一件事是,使用的WeakReference&LT; T&GT; 使得它很难删除条目 - 当原始值是垃圾回收,你不会是能够找到其散列code了。你可能只是需要创建一个新的的HashSet 与仍然活着的条目。或使用您自己的LRU缓存,正如评论。

One thing I hadn't considered is that using WeakReference<T> makes it hard to remove entries - when the original value is garbage collected, you're not going to be able to find its hash code any more. You may well need to just create a new HashSet with the still-alive entries. Or use your own LRU cache, as mentioned in comments.

这篇关于冲压/标记/品牌对象实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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