Xna 首先加载图像,然后它不是';T(新华社)

Xna 首先加载图像,然后它不是';T(新华社),xna,c#,Xna,C#,我现在很困惑 我有以下课程:(只是课程的一部分): IngameImage只是我自己的一个类,但实际上它包含一个Texture2D(以及其他一些东西)。 在另一个类中,我通过反序列化XML文件加载GUI按钮列表 public static GUI Initializazion(string pXMLPath, ContentManager pConMan) { GUI myGUI = pConMan.Load<GUI>(pXMLPath); G

我现在很困惑

我有以下课程:(只是课程的一部分):

IngameImage只是我自己的一个类,但实际上它包含一个Texture2D(以及其他一些东西)。 在另一个类中,我通过反序列化XML文件加载GUI按钮列表

public static GUI Initializazion(string pXMLPath, ContentManager pConMan)
    {
        GUI myGUI = pConMan.Load<GUI>(pXMLPath);
        GUIWindow.StandardBackgroundImage = new   
        IngameImage(pConMan.Load<Texture2D>(myGUI.WindowStandardBackgroundImagePath),
                 Vector2.Zero, 1024, 600, 1, 0, Color.White, 1.0f,
                 true, false, false);
        System.Console.WriteLine("Image loaded? " +  
                                (GUIWindow.StandardBackgroundImage.ImageStrip != null));
        myGUI.Windows = pConMan.Load<List<GUIWindow>>(myGUI.GUIFormatXMLPath);
        System.Console.WriteLine("Windows loaded");

        return myGUI;
    }
publicstaticgui初始化(字符串pXMLPath,contentmanagerpconman)
{
GUI myGUI=pConMan.Load(pXMLPath);
GUIWindow.StandardBackgroundImage=新建
IngameImage(pConMan.Load(myGUI.WindowsStandardBackgroundImagePath),
矢量2.0,1024600,1,0,彩色,白色,1.0f,
真、假、假);
System.Console.WriteLine(“已加载映像?”+
(GUIWindow.StandardBackgroundImage.ImageStrip!=null));
myGUI.Windows=pConMan.Load(myGUI.GUIFormatXMLPath);
System.Console.WriteLine(“Windows加载”);
返回myGUI;
}
这行代码是:System.Console.WriteLine(“已加载映像?”+
(GUIWindow.StandardBackgroundImage.ImageStrip!=null)); 打印“真”。 要加载GUI窗口,我需要一个“空”构造函数,如下所示:

public GUIWindow()
    {
        Name = "";
        Buttons = new List<Button>();
        ImagePath = "";
        System.Console.WriteLine("Image loaded? (In win) " + 
                                (GUIWindow.StandardBackgroundImage.ImageStrip != null));
        //Image = new IngameImage(StandardBackgroundImage);
        //System.Console.WriteLine(
        //Image.IsActive = false;
        SelectedButton = null;
        IsActive = false;
    }
publicguiwindow()
{
Name=“”;
按钮=新列表();
ImagePath=“”;
System.Console.WriteLine(“已加载映像(在win中)”+
(GUIWindow.StandardBackgroundImage.ImageStrip!=null));
//图像=新IngameImage(标准背景图像);
//System.Console.WriteLine(
//Image.IsActive=false;
SelectedButton=null;
IsActive=假;
}
如您所见,我在构造函数中注释了行。因为:否则这将崩溃。 这里是System.Console.WriteLine(“已加载图像(在win中)”+ (GUIWindow.StandardBackgroundImage.ImageStrip!=null)); 没有打印任何内容,它只是崩溃并显示以下错误消息:

生成内容引发NullReferenceException:对象引用未设置为对象实例

为什么会发生这种情况? 在程序想要加载列表之前,它会打印“true”。但是在构造函数中,因此在加载列表时,它会打印“false”。
有谁能告诉我为什么会发生这种情况以及如何修复它吗?

我对NullReferenceException的最佳猜测是
GUIWindow.StandardBackgroundImage
为null,因此当您尝试访问
GUIWindow.StandardBackgroundImage.ImageStrip
时,它会引发此异常

您熟悉Visual Studio调试器吗?如果不熟悉,您应该熟悉。我会设置一些断点,并逐步执行任何读取或写入
StandardBackgroundImage
的代码

实际上,您的组织是可以改进的。为什么
StandardBackgroundImage
GUIWindow
类的静态字段?它应该是加载它的类的字段-无论
初始化方法在哪里。然后将它传递给GUIWindow的构造函数

您将
StandardBackgroundImage
字段视为一个全局字段,因此感受到了该决策的影响-有些东西正在阅读和修改它,而您无法跟踪它们的操作顺序


使用您的调试器。NullReferenceException表示您正试图使用设置为null的变量执行某些操作。您是否使用MSDN中的代码?异常是在构建内容时引发的,而不是在运行应用程序时引发的,这一事实应该是一个线索。为什么此代码在内容构建过程中运行?您想做什么mpile作为可能导致其运行的内容?应M0rgenstern的请求迁移到堆栈溢出,希望有人能进一步了解情况。问题不在于GUIWindow.StandardBackgroundImage。这两种情况下都不是空的。问题似乎确实是存储在StandardBackgroundImage.ImageStr中的Texture2Dip。在第一次检查中,它不是空的,然后在构造函数中它是空的,在所有事情之后它不是空的。它在构造函数中只是空的。因为其余的:不要担心。每个窗口都有一个映像属性,它保存自己的映像。全局StandardBackgroundImage只是为了在没有加载任何规范的情况下给窗口一个标准映像ial图像。好吧,既然上面的说法是错误的,而且显然你想保持全局性……这里有另一个想法:我相信ContentManager使用一个单独的线程。可能静态
StandardBackgroundImage
尚未复制到该线程。如果是这种情况,你可以用[
volatile
关键字][2]来补救。尝试一下,看看它是否是固定的。它似乎没有使用不同的线程。我使用了volatile关键字,它抛出了与以前相同的错误。我不想保留全局,我会改变它,如果我可以考虑任何其他解决方案,但老实说,我看不到任何解决方案。好吧,如果你已经调试并确信构造函数看不到ic变量,但它不是空的,您还有两个选择:您可以创建一个新的C#项目,并尝试模拟这种行为。基本上,为了演示目的,尽可能简化它,但它会做同样的事情。您将发现您的问题,或者进行测试要压缩并发送给其他人查看的项目。您的另一个选择是深入了解ContentManager类及其加载方法的XNA源代码,看看它在做什么。如果您希望我将此迁移到Stack Overflow,请告诉我,您可能会得到更多答案。
public GUIWindow()
    {
        Name = "";
        Buttons = new List<Button>();
        ImagePath = "";
        System.Console.WriteLine("Image loaded? (In win) " + 
                                (GUIWindow.StandardBackgroundImage.ImageStrip != null));
        //Image = new IngameImage(StandardBackgroundImage);
        //System.Console.WriteLine(
        //Image.IsActive = false;
        SelectedButton = null;
        IsActive = false;
    }