C# 如何深度复制包含lambda表达式的对象?

C# 如何深度复制包含lambda表达式的对象?,c#,lambda,deep-copy,C#,Lambda,Deep Copy,又是我,关于我的超级男人游戏。我切换到组件系统,以便对象可以由数据驱动。一切正常,但我遇到了一个问题 “我的对象”具有由输入文件指定的状态。这些状态具有将它们转换到其他状态的触发器。状态更改的条件也在输入文件中,并解析为lambda表达式。现在我需要深度复制我的对象,我需要lambda引用副本的成员,而不是原始的成员。当程序加载时,原始文件从文件中加载,但可以在加载后的任何时间复制(想想发射的射弹) 下面是一段大大简化的代码: class StateComponent { // when

又是我,关于我的超级男人游戏。我切换到组件系统,以便对象可以由数据驱动。一切正常,但我遇到了一个问题

“我的对象”具有由输入文件指定的状态。这些状态具有将它们转换到其他状态的触发器。状态更改的条件也在输入文件中,并解析为lambda表达式。现在我需要深度复制我的对象,我需要lambda引用副本的成员,而不是原始的成员。当程序加载时,原始文件从文件中加载,但可以在加载后的任何时间复制(想想发射的射弹)

下面是一段大大简化的代码:

class StateComponent
{
    // when the whole entity is cloned, it will get a clone of
    // DependentComponent as well as a clone of this StateComponent.
    private OtherComponent DependentComponent;

    // there is a function to register dependencies. The entity that owns
    // me also owns DependentComponent, and registered it with me.

    public StateComponent Clone()
    {
        // what should I do here to make the lambda deep copied?
    }

    public void LoadFromXml(XElement node)
    {
        State state = new State();
        LambdaExpression lambda = DynamicExpression.ParseLambda(from xml stuff)
        Delegate condition = lambda.Compile();
        Action effect = LoadTriggerEffect();
        state.AddTrigger(condition, effect);

        // add state to my list of states
    }

    private Action LoadTriggerEffect()
    {
        Action action = new Action(() => { });
        if ( some stuff from the input file )
            action += () => { DependentComponent.Foo(); DependentComponent.Bar = 5; }

        return action;
    }
}
更重要的是,触发器实际上会导致状态更改,然后新状态的初始值设定项调用该操作,但我在这里对其进行了简化


所以问题是,当我深度复制这个组件时,或者无论如何尝试复制时,我不知道如何使lambda引用DependentComponent的副本实例,而不是原始组件的副本实例。我已经确保实体的深层副本得到了一个新的DependentComponent,但lambda只是引用了原始副本。委托创建后是否基本上锁定到特定实例?我需要创建一个新的吗?我不想再次从文件中加载整个实体。

为什么不将其作为lambda的参数

Action<OtherComponent> action = new Action<OtherComponent>((null) => { });
if ( some stuff from the input file )
    action += x => { x.Foo(); x.Bar = 5; }
Action Action=新操作((null)=>{});
if(输入文件中的某些内容)
action+=x=>{x.Foo();x.Bar=5;}

如果您需要不止一个依赖组件,还可以传递this指针,如果您想在不同类的对象之间交换lambda,请使用接口…

表达式树是不可变的,因此如果其中有对象引用,它们将指向原始对象。要深入复制它,你需要某种具有替代性的访问者;我在某处有一些类似的代码,但这是一个很大的工作。当然,如果其中没有特定于对象的引用,您可以非常安全地“按原样”使用它


假设您指的是
LambdaExpression lambda
字段;我不熟悉您是如何解析它的,所以我无法评论这有多容易,但这里的一个常见选项是参数化lambda;将目标对象作为参数传入,您可以在运行时将lambda与多个不同的对象一起重新使用(只要它们是适当的类型)。

我认为他实际上想要更改它。当原始lambda正在访问本地属性时,他希望复制的lambda正在访问新对象的属性;所以我说:让lambda访问参数的属性(
Expression.parameter
),并将
this
传递到两个位置的相同(不可变和不变)lambda中。我实际上已经弄明白了这一点,并且在发布后不少于1分钟就这样做了。但我仍然对这个问题是否有一个普遍的解决方案感兴趣。