シリアル化とIDの問題は、シリアル化プロセスが実際に元のオブジェクトのクローンを作成することです。
ObjectInputStream ois = ...;
SomeThing y = (SomeThing)ois.readObject()
できないと(それがケースでなければなりませんけれども、そのx.equals(y)
)あなたが本当にして行きたいと思った場合は
をそのx == y
を強制しませんが続く
SomeThing x = ...;
ObjectOutputStream oos = ...;
oos.writeObject(x);
、ほとんどの時間アイデンティティ、あなたが書かれたインスタンス(シングルトンのように)実際には同じストリーム利回りからクラスのインスタンスを読んだことを、強制カスタムシリアル化コードを書く必要があるだろう。これは、権利を取得するのは難しいです、と私は使用するAPIは非常に困難になるだろう魔法の鍵を宣言するために、単純にそれを行うために、開発者を強制的に、と思います。
今日では、一つはenum
Sを使用して、シングルトンの文字を強制するためにVMに頼ることができます。
enum MyMetaDataKey implements HyptheticalMetaDataKeyInterface {
TITLE(String.class),
WIDTH(Integer.class);
private final Class<?> type;
private MyMetaDataKey(Class<?> t) { type = t; }
public Class<?> getType() { return type; }
}
欠点は、あなたが、あなたが手動で全体のサポートコードをコーディングする必要がありますので、あなたは、(あなたはそれはしかし、インターフェイスを実装することができます)、共通の基本クラスから継承するENUM宣言することができないこと、であるMetaDataKey
かもしれませんあなたに何度も何度も何度もお世話します。上記の例では、すべてこのgetType
は抽象基本クラスによって提供されているはずですが、enum
を使用していたためできませんでした。
質問の第2の部分について...残念ながら、私はC#でそれに答えて十分に堪能ではありません(すでに言及されているプレーンなプライベートクラスのソリューションに加えて)。
言い換えれば()Ben氏の答えに対するコメントに出てくるを編集してください。同様のことを達成するための1つの解決方法(意味では、Javaソリューションと同じように使用可能です) :
class MyStuff {
private static MetaDataKey<String> key = new MetaDataKey<String>(new Guid(), typeof(String));
}
にとして使用することができる
[Serializable]
public class MetaDataKey<T> {
private Guid uniqueId;
private Type type;
public MetaDataKey(Guid key, Type type) {
this.uniqueId;
this.type = type;
}
public override boolean Equals(object other) {
return other is MetaDataKey && uniqueId == ((MetaDataKey)other).uniqueId;
}
}
C#の-languageの違反を無視してください。私はそれを使用してからそれはあまりにも長いです。
これは有効な解決策のようです。しかし、問題はkey
定数の初期化にあります。上記の例のように実行すると、アプリケーションが起動されるたびに新しいGuid値が作成され、MyStuff
のメタデータ値の識別子として使用されます。たとえば、プログラムの前回の呼び出し(つまり、ファイルに保存されている)からシリアル化されたデータがある場合、別のGuid値MyStuff
のメタデータキーを持つキーがあります。デシリアライズ後、効果的に、任意のリクエストは、Guidsが異なるため、失敗します。必要に応じて
class MyStuff {
private static Guid keyId = new Guid("{pre-define-xyz}");
private static MetaDataKey<String> key = new MetaDataKey<String>(keyId, typeof(String));
}
今、物事は動作しますが、キーのGUIDを維持する負担はあなたに来ている:だから、例の作業を行うために、あなたは、永続的な事前定義されたGUIDを持っている必要があります。これは、私が思うに、Javaソリューションがこのかわいい匿名サブクラスのトリックで避けようとしていることです。
クラスが匿名でなければならない理由はありますか?なぜ、通常のC#静的内部クラスは機能しませんか? – Gabe
Gabe: 'class FooKey:MetaDataKeyのようなものです。 {}'? –
cdmckay