在C#中动态重新加载类(循环遍历所有实例)

时间:2011-03-28 17:46:19

标签: c# game-engine

我正在使用C#构建游戏引擎,我的目标是能够动态编辑和重新加载也用C#编写的组件类。从我通过几个不同的例子发现的,确实可以将一个程序集(DLL)加载到AppDomain中,然后卸载它并重新加载一个已编辑/重新编译的版本。通过我自己的测试,我发现它运行得很好,唯一的问题是消除对该对象的特定实例的所有运行时引用,以便可以重新加载和替换它。

基本上,我希望能够获得对特定对象的所有引用的列表。我知道在C#中这可能是完全不可能的,因为它在很大程度上取决于存储引用特定对象的所有对象的列表的语言。只要它正常工作,实施是否非常缓慢并不重要。

我在这里粘贴了一些伪代码,以便我能够做到: http://nopaste.dk/p3059

我知道我能做到的一种方法是拥有自己的“弱引用”类型,我基本上无处不在,并且永远不会创建对象的直接引用。这看起来有点令人头疼,但如果对对象的任何真实引用仍然存在,至少卸载AppDomain会抛出异常。基本上,这会将管理权交到我手中,而不是自动化和可执行。

如果你知道这样做的好方法,或者你认为我做了一些根本错误的事情,请随意说出来,谢谢!

3 个答案:

答案 0 :(得分:1)

如果您尚未查看,请务必查看Managed Extensibility Framework。它将为您节省大量时间,而不是重新发明轮子。

答案 1 :(得分:0)

WeakReference已经存在。这是一个不错的主意。

http://msdn.microsoft.com/en-us/library/ms404247.aspx

此外,要以类似时尚的“插件”加载.dll,请查看MEF。它为你抽象了很多工作。

http://mef.codeplex.com/

答案 2 :(得分:0)

如果您确实自行管理这个问题,请记住,AppDomain上的所有引用都将通过代理引用而不是实际指向实例。您的所有编组实例也必须从MarshalByRefObject派生,以便生成代理。

您可以使用的一个选项是组织您的游戏,以便几乎整个游戏都在一个AppDomain中,主AppDomain是一个相对较浅的托管shell。这可以最大限度地减少您在游戏实际运行时进行的跨AppDomain调用的次数,这种调用往往会很慢。要重新加载加载项,您需要:

  • 使用可以维护引用的DataContractSerializer等序列化您的游戏状态。
  • 卸载整个游戏AppDomain
  • 加载新游戏AppDomain
  • 反序列化您的游戏状态,现在将在重建时解析为新加载的类型。