【问题标题】:While initializing, it says "Object reference not set to an instance of an object"初始化时,它说“对象引用未设置为对象的实例”
【发布时间】:2010-07-15 06:57:48
【问题描述】:

我对 C# 完全陌生,我遇到了一个错误,我无法猜测它为什么会发生。这是上下文:

我有一个 DataPair 类,就是一对数据(字符串、浮点数)。我还有另一个类 DataSet,它是一个 DataPairs 数组。

DataSet 有两个私有成员:

private DataPair [] _datapair;
private int _size;

DataSet 的构造函数对 _datapair 不做任何事情,将 _size 设置为 0。

我用 Append 方法填充 DataSet,它执行如下操作:

public void Append(DataPair pair)
{
    _datapair[_size] = new DataPair(pair);
    _size++;
}

我从另一个方法 FillFromFile 调用 Append:

public void FillFromFile(string filepath)
{
    try
    {
        if (System.IO.File.Exists(filepath))
        {
            System.IO.StreamReader sr = new System.IO.StreamReader(filepath);
            string[] currentdata;
            while (sr.Peek() >= 0)
            {
                currentdata = sr.ReadLine().Replace(',', '.').Trim().Split(';');
                this.Append(new DataPair(currentdata[0],  System.Convert.ToSingle(currentdata[1])));
            }

            sr.Close();
        }
    }
    catch (Exception e)
    {
        Console.WriteLine("Error in datafile: {0}", e.ToString());
    }
}

它似乎应该可以工作:它为每个 Append 创建(新)一个新的 DataPair。

但执行时出现此错误:

函数Append中的“对象引用未设置为对象的实例”。

发生了什么?

【问题讨论】:

  • 与您的问题完全无关,但您正在传递“new DataPair(currentdata[0], System.Convert.ToSingle(currentdata[1]))”并且在您执行“_datapair[_size”的方法中] = 新数据对(对);"。您不需要这样做,因为您正在创建 2 个对象,而您只需要一个对象。如果在最终解决方案中使用数组,那么 _datapair[_size] = pair 就足够了。阅读 C# 中的值类型和引用类型

标签: c#


【解决方案1】:

您尚未初始化 _dataPair。 _datapair = 新数据对[大小];

无论如何,Append 中的代码是错误的。您不能以这种方式增加数组的大小。使用List<DataPair> 而不是数组可能会更好。

【讨论】:

  • 所以我将不得不多次调整它的大小,因为我不知道初始大小。使用列表怎么样?非常感谢!
  • 你必须使用一个List,但不要忘记初始化它。
  • gnah 太慢了 ;D 但你是对的,当他尝试插入新的数据对时,_datapair 为空。一些建议: _datapair 是数据对数组的糟糕名称,请尝试使用 _datapairs。并且您应该在 finally 块中关闭流读取器或使用 using 语句,否则如果您的 try 块中发生异常,文件将保持打开状态直到您的程序关闭。顺便说一句:使用调试器很容易发现这类错误。
【解决方案2】:

可能 _datapair 尚未初始化。您直接调用尚未初始化的 _datapair[_size] 。 为什么不使用 Collection 顺便说一句?

private List<DataPair> _datapair = new List<DataPair>();

public void Append(DataPair pair)
{
    _datapair.Add(pair);
}

_size 已经过时了,你可以使用 _datapair.Count()

【讨论】:

    【解决方案3】:

    我会像这样使用List&lt;DataPair&gt;

    private readonly List<DataPair> _datapair = new List<DataPair>();
    

    那么你的 append 方法就变成了:

    public void Append(DataPair pair)
    {
        _datapair.Add(pair); 
    }
    

    【讨论】:

      【解决方案4】:

      这是因为你的 _dataPair 数组没有被实例化:

      private DataPair [] _datapair = new DataPair[] { };
      

      【讨论】:

        【解决方案5】:

        您的代码创建了一个新的DataPair,但从未初始化DataPair 数组。因此,datapair 引用 null 并且任何取消引用它的尝试都将导致 NullReferenceException。您需要在访问它之前对其进行初始化:

        _datapair = new DataPair[someSize];
        

        不过,我认为使用列表会更好,因为数组不会自动调整大小:

        private readonly IList<DataPair> datapairs;
        
        ...
        
        datapairs = new List<DataPair>();
        
        ...
        
        datapairs.Add(new DataPair(...));
        

        【讨论】:

          【解决方案6】:

          使用列表而不是数组,因为您在编译时不知道需要多少数据对。

          【讨论】:

            【解决方案7】:

            您不需要在Append 中创建新的DataPair,因为您已经在对Append 的调用中创建了DataPair 对象,所以您只能这样做:

            public void Append(DataPair pair)
            {
                _datapair[_size] = pair;
                _size++;
            }
            

            另外,_size 是不必要的,因为所有 C# 数组都会计算它们的元素。你最好使用List,或者如果你坚持使用数组,你可以这样做:

            public void Append(DataPair pair)
            {
                _datapair[_datapair.Count()] = pair;
            } 
            

            而且,当Append 尝试将新对象添加到_datapair 数组(不是数组,而是对 DataPairs 数组的未初始化引用)时,会引发错误。所以正如下面的答案所说,你必须初始化数组,但你必须知道它的最大或想要的大小:

            private DataPair [] _datapair = new DataPair[10];
            

            因为我相信你不知道大小,你应该使用 List 而不是你的数组。

            private List<DataPair> _datapair = new List<DataPair>();
            
            public void Append(DataPair pair)
            {
                _datapair.Add(pair);
            }
            
            public void FillFromFile(string filepath)
            {
                try
                {
                    if (System.IO.File.Exists(filepath))
                    {
                        System.IO.StreamReader sr = new System.IO.StreamReader(filepath);
                        string[] currentdata;
                        while (sr.Peek() >= 0)
                        {
                            currentdata = sr.ReadLine().Replace(',', '.').Trim().Split(';');
                            this.Append(new DataPair(currentdata[0],  System.Convert.ToSingle(currentdata[1])));
                        }
            
                        sr.Close();
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine("Error in datafile: {0}", e.ToString());
                }
            }
            

            如果你想知道列表的大小,调用_datapair.Count(),如果你想访问列表中的第4个元素,_datapair[4] = null

            【讨论】:

              猜你喜欢
              • 2011-03-17
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多