カスタム クラスのインスタンスを Session に入れ、それを引き出す場合、Session の内容への参照ではなく、Session の内容の COPY として出力する必要があります。これが私が持っているもので、例として骨抜きにしています。
protected void btnSubmit_Click(object sender, EventArgs e)
{
Company selectedCompany = new Company("1234"); //a company code
selectedCompany.AnotherClass.Value1 = "hello";
Session["OLD.Company"] = selectedCompany;
Company newCompany = (Company)Session["OLD.Company"]; //I want this to be a COPY of what's in Session, not a reference to it.
newCompany.AnotherClass.Value1 = "goodbye";
Session["NEW.Company"] = newCompany;
}
ステップスルーしてセッション変数を監視したところ、上記のコードにより、OLD.Company と NEW.Company の両方の AnotherClass.Value1 が「さようなら」に設定されます。
最初の Google 検索で、Company クラスに IClonable を実装する方向に導かれました。私は次のことを試しましたが、役に立ちませんでした:
public class Company : ICloneable
{
//properties...
//constructors...
public object Clone()
{
return this.MemberwiseClone();
}
}
その後...
protected void btnSubmit_Click(object sender, EventArgs e)
{
Company oldCompany = (Company)Session["OLD.Company"];
Company newCompany = (Company)oldCompany.Clone();
newCompany.AnotherClass.Value1 = "goodbye";
Session["NEW.Company"] = newCompany;
}
それでも、両方の OLD.Company と NEW.Company の Value1 が「さようなら」になります。これは、MemberwiseClone() が「浅い」コピーを作成するためだと思われます。ここでの問題は、Value1 が参照型 (AnotherClass) であるプロパティの値であることです。
しかし同時に、ICloneable を実装しないと書かれているこのサイトも見つけました。したがって、ここでの私の目的のために、何をすべきか、どのようなアドバイスを追求すべきかはよくわかりません。
私が見つけた他のいくつかのサイトは、これのいくつかのバージョンを示しています:
public static object CloneObject(object obj)
{
using (MemoryStream memStream = new MemoryStream())
{
BinaryFormatter binaryFormatter = new BinaryFormatter(null, new StreamingContext(StreamingContextStates.Clone));
binaryFormatter.Serialize(memStream, obj);
memStream.Seek(0, SeekOrigin.Begin);
return binaryFormatter.Deserialize(memStream);
}
}
これには、クラスをシリアライズ可能にする必要があります --- これはおそらく問題ありません (シリアライゼーションについて読む必要があります) が、ICloneable を使用しないことに関する記事を読んだ後、 ICloneable ソリューション。