得到NullReferenceException当我使用相同的代码但表达式不同时

时间:2016-04-02 13:16:03

标签: c#

我正在写一个关于游戏角色数据的项目。

数据文档中的每个字符都有四种类型,Lv1和LvMAX,以及HP,STR,VIT,INT,MEN。

我在中间部分使用前一个代码,当我用它来获取一些数据时得到NullReferenceException:

int x = CD.Parameters.Basic.Awaked.Force.Lv1.STR;

强制将为空。但是当我在中间部分使用buttom时,Force不会为空。

这两者有什么区别?

以下代码

public class ParamType
{  
    public ParamLv Mebius, Force, Aegis, Magius;
    string cost;
    DataRow[] Datas;
    List<int> ToMebius = new List<int>(), ToForce = new List<int>(), ToAegis = new List<int>(), ToMagius = new List<int>(); //HP, HP, STR, STR, VIT, VIT, INT, INT, MEN, MEN

    public ParamType(SData Data, bool awaked)
    {
        if (awaked)
        {
            Data.CharaID = CharaCOM.AwakedID(Data.CharaID);
        }
        Datas = DataCOM.Search(Data.CharaID, Data.DTs.Source, Data.TitleP.Start[(int)DataTitle.CharacterParams], Const.COL_CHARACTER_ID, Const.COL_CHARACTER_ID);
        cost = DataCOM.Search(Data.DTs.Source, Data.CharaID, Const.COL_COST, 0, Data.TitleP.Start[(int)DataTitle.CharacterParams], Const.COL_CHARACTER_ID_WITH_TYPE);

        List<int>[] SArray = { ToMebius, ToForce, ToAegis, ToMagius };

        for (int i = 0; i < Datas.Length; i++)
        {
            SArray[i] = new List<int>();
            for (int j = Const.COL_PARAM_MIN; j < Const.COL_PARAM_MIN + Const.COL_PARAM_LENGTH; j++)
            {
                SArray[i].Add(Convert.ToInt32(Datas[i][j]));
            }
        }

        /*
        this will send NullReference Exception

        ParamLv[] PLArray = new ParamLv[4];

        for (int i = 0; i < SArray.Length; i++)
        {
            PLArray[i] = new ParamLv(Data, SArray[i]);
        }
        */

        /*
        This won't get exception and I can get correct data I want.

        Mebius = new ParamLv(Data, SArray[0]);
        Force = new ParamLv(Data, SArray[1]);
        Aegis = new ParamLv(Data, SArray[2]);
        Magius = new ParamLv(Data, SArray[3]);
        */
    }

    public class ParamLv
    {
        public Params Lv1, LvMax;
        List<int> ToLv1 = new List<int>(), ToLvMAX = new List<int>(); //HP, STR, VIT, INT, MEN

        public ParamLv(SData Data, List<int> ParamsL)
        {

            for (int i = 0; i < ParamsL.Count; i += Const.COL_PARAM_MIN_MAX_GAP)
            {
                ToLv1.Add(ParamsL[i]);
                ToLvMAX.Add(ParamsL[i + 1]);
            }
            Lv1 = new Params(Data, ToLv1);
            LvMax = new Params(Data, ToLvMAX);
        }

        public class Params
        {
            //some method and properties to get or set Parameters. 
        }
    }

请告诉我是否还有不好的事情,这是我第一次在这里提问,所以如果我做错了,请告诉我。感谢@MicroVirus,@ Mororiy和@mvikhona告诉了我的错误。

1 个答案:

答案 0 :(得分:0)

Mebius = new ParamLv(Data, SArray[0]);
Force = new ParamLv(Data, SArray[1]);
Aegis = new ParamLv(Data, SArray[2]);
Magius = new ParamLv(Data, SArray[3]);

这样可行,因为您要将new ParamLv的引用分配给您的属性。

但在这种情况下:

ParamLv[] PLArray = { Mebius, Force, Aegis, Magius };

for (int i = 0; i < PLArray.Length; i++)
{
     PLArray[i] = new ParamLv(Data, SArray[i]);
}

您没有使用变量/属性本身填充数组,但是您正在使用属性保留的引用填充它,最后您的数组将引用4个新ParamLw,但您的属性{{1将留下Force

修改 我会尝试解释它有点不同。假设你有这段代码:

null

此时 ParamLv[] PLArray = { Force }; 的值与 PLArray[0]的值相同,但Force不是{{1 }}。 你这样做的那一刻:

PLArray[0]

Force会返回对PLArray[0] = new ParamLv(Data, null); 的引用,您将其分配给new ParamLv(Data, null),但就像我在new ParamLv之前所说的那样PLArray[0],所以{{ 1}}将保持不变。

如果这不能很好地解释,请尝试查看这段代码,它会做你想要做的事情。

PLArray[0]