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

时间:2014-10-13 23:46:14

标签: c#

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

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

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

    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);
            }

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

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

            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

3 个答案:

答案 0 :(得分:3)

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

这是倒退的,(指定设定者中的值),它应该是另一种方式。 value是参数,而不是支持字段。因此,您的设置无效,并且您获得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
}

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

答案 1 :(得分:0)

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

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

希望有所帮助。

答案 2 :(得分:0)

`public string ItemDescription {

    get { return itemDescription; }

    set { value = itemDescription; }

} `

您在设置部分中有错误的代码,应将值分配给itemDescription。