C# 自给自足的通用纪念品
亲爱的程序员们 我似乎对C#中的引用如何工作缺乏一些理解 案例:C# 自给自足的通用纪念品,c#,list,generics,reference,memento,C#,List,Generics,Reference,Memento,亲爱的程序员们 我似乎对C#中的引用如何工作缺乏一些理解 案例: 我试图实现某种Memento代理,它将包装一个接口,存储我们提供给方法调用的每个参数,并将这些参数存储到一个列表中 必要时,我们可以调用RestoreState,对象将“重置”到原始状态 代码: 消费者和模型对象 纪念品 公共接口IMemento { 空添加(对象pItem); 使不动产无效(); } 公共类纪念品:伊梅门托 { 公共纪念品() { MementoList=新字典(); ReferenceList=新列表(); O
我试图实现某种Memento代理,它将包装一个接口,存储我们提供给方法调用的每个参数,并将这些参数存储到一个列表中 必要时,我们可以调用RestoreState,对象将“重置”到原始状态 代码:
消费者和模型对象 纪念品
公共接口IMemento
{
空添加(对象pItem);
使不动产无效();
}
公共类纪念品:伊梅门托
{
公共纪念品()
{
MementoList=新字典();
ReferenceList=新列表();
ObjectedGenerator=新ObjectedGenerator();
}
私有对象生成器对象生成器{get;set;}
私有字典记忆列表{get;set;}
私有列表引用列表{get;set;}
公共void添加(对象pItem)
{
布尔第一次;
long id=ObjectIDGenerator.GetId(pItem,首次输出);
如果(第一次)
{
var mementoObject=DeepCopy(pItem);
MementoList.Add(id,mementoObject);
引用列表。添加(pItem);
}
}
公共屋(
{
for(int i=0;i
额外信息我的猜测是,我在做/理解关于清单的一些错误 我还尝试了Interlocked.Exchange,使用“ref”,使用WeakReference并将对象存储到一个看守者对象中(并将该看守者存储到列表中),实现一些复制属性 而且。。。我就是看不见
我的预期结果是包含值2的PrestationInfo.Advance属性。但是它保持了看起来问题在于您对.NET中引用的理解
public void RestoreState()
{
for (int i = 0; i < ReferenceList.Count; i++)
{
object reference = ReferenceList[i];
bool firstTime;
long id = ObjectIDGenerator.GetId(reference, out firstTime);
if (MementoList.ContainsKey(id))
{
object mementoObject = MementoList[id];
reference = mementoObject;
//reference = PropertyCopy<PrestationInfo>.CopyFrom(mementoObject as PrestationInfo); //Property copy
//Interlocked.Exchange(ref reference, mementoObject); //Also tried this
}
}
}
然后这样称呼它:
public object RestoreState()
{
for (int i = 0; i < ReferenceList.Count; i++)
{
object reference = ReferenceList[i];
bool firstTime;
long id = ObjectIDGenerator.GetId(reference, out firstTime);
if (MementoList.ContainsKey(id))
{
object mementoObject = MementoList[id];
reference = mementoObject;
return reference;
}
}
return null;
}
presentationInfo2 = memento.RestoreState();
如果您希望memento跟踪对象并神奇地恢复其状态,则必须让对象本身知道memento引入耦合或使用反射来修改跟踪引用的内部状态。基本上,您不会将持久化状态反序列化到新对象中,而是使用反射将以前存储的内部状态覆盖到跟踪对象引用中
不过要小心使用WeakReference存储引用,否则您会发现自己有一个很好的内存泄漏案例 问题似乎在于您对.NET中引用的理解
public void RestoreState()
{
for (int i = 0; i < ReferenceList.Count; i++)
{
object reference = ReferenceList[i];
bool firstTime;
long id = ObjectIDGenerator.GetId(reference, out firstTime);
if (MementoList.ContainsKey(id))
{
object mementoObject = MementoList[id];
reference = mementoObject;
//reference = PropertyCopy<PrestationInfo>.CopyFrom(mementoObject as PrestationInfo); //Property copy
//Interlocked.Exchange(ref reference, mementoObject); //Also tried this
}
}
}
然后这样称呼它:
public object RestoreState()
{
for (int i = 0; i < ReferenceList.Count; i++)
{
object reference = ReferenceList[i];
bool firstTime;
long id = ObjectIDGenerator.GetId(reference, out firstTime);
if (MementoList.ContainsKey(id))
{
object mementoObject = MementoList[id];
reference = mementoObject;
return reference;
}
}
return null;
}
presentationInfo2 = memento.RestoreState();
如果您希望memento跟踪对象并神奇地恢复其状态,则必须让对象本身知道memento引入耦合或使用反射来修改跟踪引用的内部状态。基本上,您不会将持久化状态反序列化到新对象中,而是使用反射将以前存储的内部状态覆盖到跟踪对象引用中
不过要小心使用WeakReference存储引用,否则您会发现自己有一个很好的内存泄漏案例 Memento.Add需要ref参数修饰符才能访问原始引用类型指针
Memento.Add需要一个ref参数修饰符来访问原始引用类型指针 试试这个: 更改
Add
方法:
public long Add(object pItem)
{
bool firstTime;
long id = ObjectIDGenerator.GetId(pItem, out firstTime);
if (firstTime)
{
var mementoObject = DeepCopy(pItem);
MementoList.Add(id, mementoObject);
ReferenceList.Add(pItem);
}
return id; // i need my memento! LOL
}
还应添加此访问器方法:
public object GetRestoredState(long id)
{
return MementoList[id]; // you should put some range check here
}
现在您有了id,可以通过以下方式获取恢复的状态:
memento.RestoreState();
prestationInfo2 = memento.GetRestoredState(savedId); // <-- you got this when you called the Add()...
Console.WriteLine(prestationInfo2.Advance); //Expect 2, but still 1
memento.RestoreState();
prestationInfo2=memento.GetRestoredState(savedId);// 试试这个:
更改Add
方法:
public long Add(object pItem)
{
bool firstTime;
long id = ObjectIDGenerator.GetId(pItem, out firstTime);
if (firstTime)
{
var mementoObject = DeepCopy(pItem);
MementoList.Add(id, mementoObject);
ReferenceList.Add(pItem);
}
return id; // i need my memento! LOL
}
还应添加此访问器方法:
public object GetRestoredState(long id)
{
return MementoList[id]; // you should put some range check here
}
现在您有了id,可以通过以下方式获取恢复的状态:
memento.RestoreState();
prestationInfo2 = memento.GetRestoredState(savedId); // <-- you got this when you called the Add()...
Console.WriteLine(prestationInfo2.Advance); //Expect 2, but still 1
memento.RestoreState();
prestationInfo2=memento.GetRestoredState(savedId);//prestationInfo2
和RestoreState
中的局部变量reference
引用同一对象,因此要更改prestationInfo2
引用的内容,必须更改对象,不更改本地变量reference
prestationInfo2
的参考值,并且RestoreState
中的本地变量reference
引用同一对象,因此要更改prestationInfo2
引用的内容,必须更改对象,不更改局部变量的引用值reference
。这是有道理的,但是很好地遵循了memento模式的路线,因为您需要在某处存储一些键来使用memento。我现在似乎理解了我的错误。连同迈克·迪内斯库发表的评论。我确实可以制作一个映射(在我的代理中的某个地方)来“识别”参数(基于方法名/参数位置)。检查它们是否存在,如果存在,则恢复状态。非常感谢!这是有道理的,但由于您需要一些密钥,因此很好地遵循了memento模式的路线