类的参数在创建新实例时返回null

本文关键字:实例 返回 null 参数 创建 新实例 | 更新日期: 2023-09-27 18:26:27

在我的Item类中,我有这两个变量。

    public string ItemDescription
    {
        get { return itemDescription; }
        set { value = itemDescription; }
    }
    public string itemDescription;

我知道有两个相同的变量是多余的,但我现在正在使用它们进行调试。每个继承的项都有这样的构造函数。

    public Log()
    {
        //other stuff
        itemDescription = "A log.";
        ItemDescription = itemDescription;
    }

我像这样显示ItemDescription。

 if (item.ItemSlotRectangle.Contains(MousePosition) && item.ItemName != "empty")
            {
                spriteBatch.DrawString(font, item.ItemDescription, new Vector2(item.ItemSlotPosition.X, item.ItemSlotPosition.Y - 20), Color.Black);
            }

这在某些时候是有效的。当我创建一个项目并将其设置在地面上时,我可以查看描述。但是,当我创建一个新项目并尝试查看描述时,我在该项目上得到了一个null错误。draw方法中的ItemDescription变量。

我创建了一个这样的新项目。

            if (item.ItemSlotRectangle.Contains(mp) && item.ItemName != "empty")
            {
                Item newItem = new Item();
                newItem.ItemName = item.ItemName;
                newItem.Texture = item.Texture;
                newItem.ItemDescription = item.ItemDescription;
                return newItem;
            }

我的问题是,当纹理和名称起作用时,这怎么会为ItemDescription返回null?我想我不完全理解创建类的新实例是如何工作的。

编辑:为了清晰起见,我将尝试添加更多的代码,并描述我要做的事情。每次创建一个新项目时,我都会循环遍历和列出,并调用一个方法,该方法会返回列表中该项目的输出。

            if (recipe.CheckForItemsNeeded(player) != null)
            {
                Output = recipe.Output;
                SetItemPositionInTable(Output);
            }

输出的类型为Item。SetItemPositionInTable方法应该绘制项目,这样我就可以点击它并制作它。方法如下。

             for (int i = 0; i < CraftingTableItems.Count(); i++)
        {
            if (CraftingTableItems[i].ItemName == "empty")
            {
                CraftingTableItems[i].ItemName = output.ItemName;
                CraftingTableItems[i].Texture = output.Texture;
                break;
            }
            else if (CraftingTableItems[i].ItemName == output.ItemName)
            {
                break;
            }
            //fix this
            else if (CraftingTableItems[i].ItemName != "empty" && output.ItemName == "empty")
            {
                CraftingTableItems[i].ItemName = output.ItemName;
                break;
            }
        }

这个方法现在一团糟,但那是另一个问题。当我打出来的时候,我意识到我忘记了if循环中的一行来设置描述。。。问题已解决:P

类的参数在创建新实例时返回null

    set { value = itemDescription; }  // should be  itemDescription = value

这是向后的(在setter中赋值),应该是另一种方式。值是参数,而不是支持字段。因此,您的设置不起任何作用,在ItemDescription属性中获取值的唯一方法是通过设置(小写)itemDescription = "A log."; 的构造函数

public string ItemDescription
{
    get { return itemDescription; }
    set { itemDescription = value; }  // correct
}

在幕后,set {...}被编译器重写为如下方法:

void set_ItemDescription(string value) { ... }

所以您的原始代码是分配给参数的,而不是后台字段。

此外,由于itemDescription是属性的后备字段,因此构造函数有一个冗余赋值(itemDescription=itemDescription)

public Log()
{
    //other stuff
    itemDescription = "A log.";
    ItemDescription = itemDescription;  // <--- redundant
}

还有一个建议;除非您显示的代码是一个工厂方法,否则您应该编写一个"复制"构造函数,或者实现一个Clone()或copy()方法,而不是从外部代码中显式复制对象属性。类应该知道如何复制或实例化完全初始化的实例,并且应该只在类内或工厂中编写代码。除非您正在反序列化,否则您的构造函数或工厂应该生成一个完全初始化的对象,即使在复制另一个对象时也是如此。

类的值类型成员永远不会为null。另一方面,在显式初始化之前,可为null的值和类成员将为null。字符串可以为null,因此在未初始化ItemDescription时它为null。您可以比较名称等空字符串,但当尝试绘制空字符串时,会出现异常。

以下是关于值类型与引用类型的链接:http://msdn.microsoft.com/en-us/library/t63sy5hs.aspx

希望能有所帮助。

`公共字符串ItemDescription{

    get { return itemDescription; }
    set { value = itemDescription; }
} `

集合部分中的代码错误,应将值分配给itemDescription。