我正在寻找一种方法来排序对象列表(任何可能的类型),以便无论发生在对象,只要他们没有被破坏,顺序保持不变(所以hashCode不是一个好主意,因为在某些类中它会随时间变化),因此我在考虑在内存中使用对象的地址,但我不确定它总是保持不变(例如,垃圾收集呼叫可以改变地址吗?)。然而,我正在寻找对象的属性(任何类型),只要对象没有被销毁,这些属性也会保持不变。他们有没有?如果是的话,他们是什么?在C中的对象的不可变属性#
回答
是的,对象可以通过垃圾收集器在内存中移动,除非你明确地要求它不要(并且通常建议让GC做它的事情)。
这里需要的是一个边桌:创建一个由对象自己键入的字典,并为值放上你喜欢的任何东西(可以是对象的原始哈希码,甚至是随机数)。在排序时,按该侧键进行排序。现在,如果例如对象a在该字典中的值为“1”,它将总是首先排序 - 无论a做了什么更改,因为您会在侧面字典中查找关键字和代码不知道去那里改变它(当然,你要小心保持这个数据不变)。您可以使用weak references来确保您的字典条目在没有其他对象引用的情况下消失。
当然,只能通过内存地址进行排序。所以不是所有类型都可以按照这种方式排序,原始类型和结构不是。
另一种方式是依赖于某个接口,你需要每个实例都可以返回一个Guid。这是在构造函数中创建的,没有改变。
public interface ISortable
{
Guid SortId { get; }
}
class Foo : ISortable
{
Foo()
{
SortId = Guid.NewGuid();
}
Guid SortId { get; private set; }
}
guid的优点是它可以在每个类中独立创建。你不需要同步,你只需给每个班级一个ID。顺便说一句:如果你使用字典中的对象作为一个键,他们不能改变它们的哈希码。它们必须是不可变的。这可能是你可能依赖的一个限制。
编辑:你可以写你的专业列表,能够保持排序。
当您从另一个列表创建列表时,您可以存储原始订单,然后您可以在任何时间点恢复订单。新的项目可以放在最后。 (有没有新的东西?)
或者你做一些更复杂的事情,并存储任何你的列表类在静态存储器中看到的任何对象的顺序。然后您可以独立地对所有列表进行排序。但是要小心你拿着的参考物,这样可以避免GC清理物体。你需要一周参考,我认为在C#中有弱引用,但我从来没有使用它们。
更好的办法是把这个逻辑放到排序类中。所以它适用于您的排序类进行排序的每个列表。
更新后的细节现在添加到问题(评论);只需在列表内容的副本之前对其进行分类...
否地址不固定。对于任意物体,没有没有明智的做法。为了您自己对象,你可以添加一些共同点,如:
interface ISequence { int Order { get; } }
static class Sequence {
private static int next;
public static int Next() {
return Interlocked.Increment(ref next); }
}
class Foo : ISequence {
private readonly int sequence;
int ISequence.Order { get { return sequence; } }
public Foo() {
sequence = Sequence.Next();
}
}
有点零碎,但它应该工作,并且可以在一个基类中使用。 Order
现在是不变的和顺序的。但只有AppDomain
特定的,并不是所有的序列化API都会尊重它(在这种情况下,您需要使用序列化回调来初始化序列)。
- 1. PHP中的可变对象属性
- 2. 可可:从不同的菜单项改变对象属性
- 3. 访问属性名称在变量中的对象属性
- 4. C#foreach改变某些对象属性?
- 5. C++中的不可变对象的可变容器
- 6. 变量中的PHP对象属性
- 7. 性能不可变的对象设计
- 8. React将属性添加到不可变的对象
- 9. Objective-c中的动态对象属性
- 10. ']对象属性不被序列化为使用c#的属性
- 11. 任何方式来从C#中的不可变对象派生可变对象?
- 12. 不可改变的属性
- 13. C#并发性:写在不同的对象属性
- 14. 抽象变量/属性? C#
- 15. 当传递给C#中的属性时,对象变为空。
- 16. 解构赋值 - C#中变量的对象属性
- 17. 迭代对象的属性(在Realm中,或者可能不是)
- 18. 在django中为对象创建不可编辑的属性
- 19. 模拟对象属性不变
- 20. 如何与可变达到的对象属性在php
- 21. 的Flex/ActionScript3的 - 对象属性/变空
- 22. 试图获取对象属性中的对象的属性
- 23. C#:函数中的'out'参数可以是对象属性/变量吗?
- 24. 可变类型'NSMutableDictionary'的属性具有'copy'属性;一个不可变对象将代替
- 25. 保留对目标c中的可变和不可变对象的计数?
- 26. 如何确保在不可变对象中定义的ArrayList的不变性?
- 27. 角$ rootScope对象属性不可访问
- 28. 我可以使用C#中的对象名称访问对象属性吗?
- 29. 属性对象是否可以到达它属于的对象?
- 30. 使用类型对象来绑定C#中的对象属性?
不确定你究竟是什么后,你可不要简单地创建一个数组,其中包含一个id引用的对象。那么简单地让这些对象负责在创建它们时自己添加它们,并在它们被破坏时将它们从列表中取出来? – Darknight 2009-08-26 11:40:08
你的问题似乎有点奇怪,也许如果你试图解释你试图解决的问题,你会得到答案,避免你目前面临的问题。回答你的一个问题:在垃圾收集期间,.NET对象在内存中移动,但在托管环境中,你永远不应该使用对象地址。 – 2009-08-26 11:44:33
我希望evry数组对象的顺序相同,所以如果你制作了一个列表副本(不是深拷贝,是对象的rhe引用的副本),并且你洗牌第二个数组,你可以很容易地使用正确的顺序,因为不变的属性。可以访问的某些值可以确保evry对象具有特定的顺序,从而不依赖于对象本身的内容。 – 2009-08-26 11:47:51