Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 自给自足的通用纪念品_C#_List_Generics_Reference_Memento - Fatal编程技术网

C# 自给自足的通用纪念品

C# 自给自足的通用纪念品,c#,list,generics,reference,memento,C#,List,Generics,Reference,Memento,亲爱的程序员们 我似乎对C#中的引用如何工作缺乏一些理解 案例: 我试图实现某种Memento代理,它将包装一个接口,存储我们提供给方法调用的每个参数,并将这些参数存储到一个列表中 必要时,我们可以调用RestoreState,对象将“重置”到原始状态 代码: 消费者和模型对象 纪念品 公共接口IMemento { 空添加(对象pItem); 使不动产无效(); } 公共类纪念品:伊梅门托 { 公共纪念品() { MementoList=新字典(); ReferenceList=新列表(); O

亲爱的程序员们

我似乎对C#中的引用如何工作缺乏一些理解

案例:
我试图实现某种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模式的路线