我正在尝试实现一种在我的应用程序中克隆元素的方法。这些元素是我定制和设计的(到目前为止,它们并没有那么复杂)。每个项目都被称为属性Children
,其中列出了更多实例(将其想象为具有多个子分支的树视图)。
我有一个名为“环境”的对象,其中包含对所有这些孩子的引用。把它想象成一个拥有我所有树木的果园。当我想复制所有内容时,我希望能够在我的“环境”类上调用“克隆”并让它给我所有内容的副本。
这一切都工作了一段时间,但经过一些更改和代码重构后,它似乎不再工作了,我不知道为什么。我可以很好地跟踪堆栈跟踪,但在这种情况下这是不可能的。这是我的错误的屏幕截图。
我还将使用序列化将我的“环境”实际保存到文件中。然而,在我能做到这一点之前,我必须让序列化工作。
无论如何,我已经分别检查了我的单个树/分支/肢体对象,它们都成功克隆。我似乎唯一无法克隆的是“环境”类(我的果园)。这是我的“环境”类的来源:
Imports gE.gEngine
Imports LuaInterface
Imports gE.gEngine.Generic
Imports Microsoft.Xna.Framework
Imports System.Runtime.Serialization
Imports System.IO
Imports System.Runtime.Serialization.Formatters.Binary
Imports gE.gEngine.WorldObjects
Imports System.Windows.Forms
Imports Microsoft.Xna.Framework.Input
Imports System.Threading.Tasks
Imports System.Threading
<Serializable()> _
Public Class Environment
Public World As WorldServices.World
Public Players As WorldServices.Players
Public Lighting As WorldServices.Lighting
Public Environment As WorldServices.Environment
Public GenericsLibrary As WorldServices.GenericsLibrary
<NonSerialized()> _
Public Lua As New LuaInterface.Lua
<NonSerialized()> _
Public SafetyContext As CommonEnum.SafetyContext = CommonEnum.SafetyContext.Safe
Public Event EnvironmentChanged(ByVal sender As Object, ByVal e As GenericEventArgument)
Public Sub call_EnvironmentChanged(ByVal sender As Object, ByVal e As GenericEventArgument)
RaiseEvent EnvironmentChanged(sender, e)
End Sub
Public Sub New()
GlobalShare.Environment = Me
InitializeLua()
Lighting = New WorldServices.Lighting()
World = New WorldServices.World()
Players = New WorldServices.Players()
Environment = New WorldServices.Environment()
GenericsLibrary = New WorldServices.GenericsLibrary()
Dim ConstraintesGroup As New WorldObjects.Group With {
.Name = "Constraintes",
.Parent = GenericsLibrary
}
Dim ordsc As List(Of gEngine.WorldObjects.Lua) = Environment.GetScripts()
ordsc.Sort(Function(x, y) x.RunIndex.CompareTo(y.RunIndex))
For Each script As gEngine.WorldObjects.Lua In ordsc
GlobalShare.Environment.RunScript(script.Source, script.Name)
Next
End Sub
Public Sub SetSafetyContext(ByVal e As CommonEnum.SafetyContext)
If e <> CommonEnum.SafetyContext.Unlocked Then
SafetyContext = e
Exit Sub
End If
Throw New Exception("Attempt to unlock safety context from unsafe Lua script!")
End Sub
Public Sub InitializeLua()
Lua("Game") = GlobalShare.Game
Lua("__Environment") = Me
Lua("gel") = New gELua(Me)
Lua.RegisterFunction("Print", Lua("gel"), Lua("gel").GetType().GetMethod("Print"))
Lua.RegisterFunction("print", Lua("gel"), Lua("gel").GetType().GetMethod("Print"))
Lua.RegisterFunction("SetSafetyContext", Lua("gel"), Me.GetType().GetMethod("SetSafetyContext"))
Lua("Vector2") = New Lua_.Lua_Vector2
Lua("Vector3") = New Lua_.Lua_Vector3
Lua("Mouse") = New Lua_.Lua_Mouse
Lua.NewTable("Helpers")
Lua("Helpers.EnumHelper") = New Helpers.EnumHelper
Dim GameTimer As New Stopwatch
Lua("Time") = GameTimer
GameTimer.Start()
Lua.NewTable("__X")
End Sub
Public Function Clone() As Environment
If [Object].ReferenceEquals(Me, Nothing) Then
Return Nothing
End If
Dim formatter As IFormatter = New BinaryFormatter()
Dim stream As IO.Stream = New MemoryStream()
Using stream
formatter.Serialize(stream, Me)
stream.Seek(0, SeekOrigin.Begin)
Return DirectCast(formatter.Deserialize(stream), [Environment])
End Using
End Function
Public Sub RunScript(ByVal scr As String, ByVal name As String)
Try
Lua.DoString(scr, name)
Catch ex As Exception
Game.CallLogEvent(Me, New GenericEventArgument("LogEvent", "Error", ex.Message))
End Try
End Sub
End Class
代码有点乱,因为我并没有因为这个特定问题而对这个特定的类感到非常困惑(我想知道为什么在我继续改变它之前它不会序列化 - 我不想造成任何同时还有更多问题)。
根据错误,它似乎正在尝试序列化我的应用程序窗口(StudioWindow),但是,我在我的应用程序中找不到对它的任何引用。
所以我并不是真的要求你们为我找到参考(据我所知,它可能隐藏在我项目的其他部分深处),但我很想找到一种方法来缩小问题的范围。我一直在评论部分并试图消除我项目的某些部分作为问题,但这有点困难,因为如果没有其他部分运行,我的应用程序的某些方面将无法运行。
任何帮助表示赞赏。如果您想了解更多信息,请询问。我可能会得到你想要的任何信息。我的代码主要是 VB.NET(尽管它是一个混合项目,所以许多其他部分都在 C# 中),因此非常感谢任何 .NET 示例/解决方案/帮助并且同样有帮助(我可以阅读两者,所以不要犹豫)。