1

オブジェクトのリスト(可能なすべてのタイプ)を並べ替えて、オブジェクトが破壊されない限り、オブジェクトに何が起こっても順序が同じになるようにする方法を探しています(したがって、hashCodeはお勧めできません)一部のクラスでは時間の経過とともに変化するため)、そのため、メモリ内のオブジェクトのアドレスを使用することを考えていましたが、これが常に同じであるかどうかはわかりません(ガベージコレクションでアドレスを変更できますか?実例?)。ただし、オブジェクトが破棄されない限り同じ状態を維持する(任意のタイプの)オブジェクトのプロパティを探しています。それらのいずれかがありますか?はいの場合、それらは何ですか?

4

3 に答える 3

1

質問 (コメント) に詳細が追加されたため、更新されました。並べ替える前に、リストの内容をコピーしてください...


いいえ、アドレスは固定されていません。また、任意のオブジェクトの場合、これを行う賢明な方法はありません。独自のオブジェクトには、次のような一般的なものを追加できます。

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 がそれを尊重するわけではありません (そのような場合は、シリアライゼーション コールバックを使用してシーケンスを初期化する必要があります)。

于 2009-08-26T11:49:50.393 に答える
0

もちろん、メモリアドレスによる並べ替えは参照オブジェクトでのみ可能です。したがって、すべての型をこのようにソートできるわけではなく、プリミティブ型と構造体はそうではありません。

もう1つの方法は、特定のインターフェイスに依存することです。この場合、この各インスタンスがGUIDを返すことができる必要があります。これはコンストラクターで作成され、変更されません。

public interface ISortable
{
  Guid SortId { get; }
}

class Foo : ISortable
{
  Foo()
  {
    SortId = Guid.NewGuid();
  }
  Guid SortId { get; private set; }
}

guidの利点は、各クラスで個別に作成できることです。同期は必要ありません。すべてのクラスにIDを指定するだけです。

ちなみに、ディクショナリ内のオブジェクトをキーとして使用している場合は、ハッシュコードを変更してはなりません。それらは不変でなければなりません。これはおそらくあなたが頼ることができる制約かもしれません。


編集:あなたは注文を維持することができるあなたの専門的なリストを書くことができます。

リストが別のリストから作成されたときに元の注文を保存しておけば、いつでも注文を復元できます。最後に新しいアイテムを置くことができます。(とにかく新しいアイテムはありますか?)

または、より洗練された方法で、リストクラスがこれまでに見たオブジェクトの順序を静的メモリに保存します。次に、すべてのリストを個別に並べ替えることができます。ただし、保持している参照に注意してください。これにより、オブジェクトがGCによってクリーンアップされなくなります。週の参照が必要になります。C#には弱い参照があると思いますが、私はそれらを使用したことがありません。

さらに良いのは、このロジックをソートクラスに入れることです。したがって、ソートクラスによってソートされたすべてのリストに対して機能します。

于 2009-08-26T11:45:08.887 に答える