[英]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.