繁体   English   中英

C# 克隆 EventHandler

[英]C# clone EventHandler

我有一个带有多个事件处理程序(除其他外)的 class:

public GameObject
{
    public event EventHandler<EventArgs> Initialize;
    public event EventHandler<EventArgs> BeginStep;
    ....
}

我希望能够将Clone() function 添加到 GameObject,它返回调用它的 object 的完全相同的副本。 我试着这样做:

    public GameObject Clone()
    {
        var clone = new GameObject()
        {
            Initialize = this.Initialize,
            BeginStep = this.BeginStep,
        };
    }

但是,它似乎正在使clone.BeginStep指向与 this.BeginStep 相同的this.BeginStep而不是复制。 那么,如何复制 EventHandler object?

你不必担心这一点。 EventHandler<EventArgs> object 是不可变的,因此 object 中的侦听器列表中的任何更改都将导致 object 获取更新后的新调用列表EventHandler<EventArgs>实例。 此更改不会出现在其他GameObject

尝试使用 += 运算符添加它。 我什至不知道可以分配一个事件。

clone.Initialize += this.Initialize;

此外,所有委托都是不可变的值类型,因此您不必担心它们指向相同的 object - 当您执行上述操作时,整个委托将被复制(如果您愿意,则克隆)。

这取决于您的事件是委托给 GameObject class 中定义的方法,还是委托给其他观察者 class 实例。

如果事件在 GameObject class 中定义的方法中处理,并且您希望克隆中的事件由克隆实例中的方法处理,则可以使用反射从原始事件处理程序中获取方法信息,使用创建新委托克隆的实例和方法名称,然后将新委托分配为克隆的事件处理程序。

    public GameObject Clone()
    {
        var clone = new GameObject();
        foreach (var target in this.Initialize.GetInvocationList())
        {
            var mi = target.Method;
            var del = Delegate.CreateDelegate(
                          typeof(EventHandler<EventArgs>), clone, mi.Name);
            clone.Initialize += (EventHandler<EventArgs>)del;
        }
        return clone;
    }

如果事件在不同的 class 中处理,则无需执行任何操作,但原始实例和克隆实例的所有事件通知都将具有相同的处理程序。 如果这不是您想要的,那么您需要在克隆后更改事件代表。

您不需要克隆事件,就像您不需要克隆源 object 的任何方法一样。 克隆时,您真正需要复制的只是成员/属性值。

你会想做一些类似于发布在Deep cloning objects上的事情

public static GameObject Clone(GameObject source)
{
    // Don't serialize a null object, simply return the default for that object
    if (Object.ReferenceEquals(source, null))
    {
        return default(GameObject);
    }

    IFormatter formatter = new BinaryFormatter();
    Stream stream = new MemoryStream();
    using (stream)
    {
        formatter.Serialize(stream, source);
        stream.Seek(0, SeekOrigin.Begin);
        return (GameObject)formatter.Deserialize(stream);
    }
}

您的 class 需要可序列化。

编辑:正如我所说,它基于我链接到的代码,我赶紧给出答案。 应该再仔细检查一下。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM