分配给类整数[]时的NullReference异常

时间:2012-04-16 14:36:13

标签: c# winforms exception-handling datagridview nullreferenceexception

我希望能够将值从Form1中的一个DataGridView传输到Form3中的另一个DataGridView。要做到这一点,我选择在3个不同的变量中过滤它们,这些变量将在类中,以便我可以稍后在Form3中访问它们。

这些是类:(我已经把它们作为一个有3个变量的单个)

public class verify1
{
    public static int[] CodUser { get; set; }
}

public class verify2
{
    public static DateTime[] DataFim{ get; set; }
}

public class verify3
{
    public static string[] Nome { get; set; }
}

Altho,当我为变量赋值时,我在第一次运行时得到NullReferenceException。

这是我用来分配值的代码:

int a = 0;
for (int i = 0; i < dataGridView1.RowCount - 1; i++)
{    
    DateTime date = Convert.ToDateTime(dataGridView1.Rows[i].Cells[2].Value);   
    if (date <= DateTime.Now)   
    {   
        verify1.CodUser[a] = Convert.ToInt32(dataGridView1.Rows[i].Cells[0].FormattedValue);    
        verify2.DataFim[a] = Convert.ToDateTime(dataGridView1.Rows[i].Cells[2].FormattedValue);
        verify3.Nome[a] = Convert.ToString(dataGridView1.Rows[i].Cells[3].Value);   
        a++;   
    }
}

现在,我不明白为什么Visual Studio说值为null。例外情况发生在以下行:

verify1.CodUser[a] =   Convert.ToInt32(dataGridView1.Rows[i].Cells[0].FormattedValue);

(这是17389)首先,不会让我走得更远。我不明白为什么它会返回null。顺便说一句,DataGridView完全满足数据。

为什么返回null?

3 个答案:

答案 0 :(得分:4)

您在verify1课程中定义了公共属性,但您从未初始化它们。他们是空的。

您需要在使用数组之前初始化数组:

int a = 0;
int rowCount = dataGridView1.RowCount;
verify1.CodUser = new int[rowCount];
verify2.DataFim = new DateTime[rowCount];
verify3.Nome = new string[rowCount];

您可能还想再看一下如何正确使用类。我猜你不需要三个单独的类,每个类都有一个静态属性。看起来您应该有一个包含三个字段的VerifyInfo类。然后,您可以将它们存储在List<T>

public class VerifyInfo
{
    public int CodUser { get; set; }
    public DateTime DataFim { get; set; }
    public string Nome { get; set; }
}

然后你的循环代码会更清晰:

var verifyInfos = new List<VerifyInfo>();

for(int i = 0; i < dataGridView1.RowCount - 1; i++)
{
    var date = Convert.ToDateTime(
        dataGridView1.Rows[i].Cells[2].Value);

    if(date <= DateTime.Now)
    {
        verifyInfos.Add(new VerifyInfo
        {
            CodUser = Convert.ToInt32(dataGridView1.Rows[i].Cells[2].Value),
            DataFim = Convert.ToDateTime(
                dataGridView1.Rows[i].Cells[2].FormattedValue),
            Nome = Convert.ToString(dataGridView1.Rows[i].Cells[3].Value)
        });
    }
}

答案 1 :(得分:1)

自动属性会自动初始化为返回类型的默认值。 您正在处理引用类型 Array引用类型 defalt值null

在这种情况下,最好避免使用自动属性,而是使用普通属性。

示例:

public class verify1
{
    static List<int> codUser = new List<int>(); //definition
    public static List<int> CodUser
    { 
       get { return codUser;} 
       set {codUser = value;} 
     }
}

在这种情况下,我明确地使用了List<T>,因为在声明时你不知道数组的大小,而且根据提供的代码,它可能会有所不同。

编辑

可以像这样使用它(在实践中就像你之前一样)

for (int i = 0; i < dataGridView1.RowCount - 1; i++)
{    
    DateTime date = Convert.ToDateTime(dataGridView1.Rows[i].Cells[2].Value);   
    if (date <= DateTime.Now)   
    {   
        verify1.CodUser[a].Add( Convert.ToInt32(dataGridView1.Rows[i].Cells[0].FormattedValue));    
        ......
        ....  
    }
}

希望这有帮助。

答案 2 :(得分:1)

不是verify1.CodUser null吗?你是如何创造它的?

编辑:

我编写了回答布鲁诺评论的回答。您必须首先初始化数组才能使用它们。要进行简单测试,请创建一个单独的项目,粘贴这两行,在调试模式下运行项目并在创建array2后设置断点:

Int32 [] array1; Int32 [] array2 = new Int32 [3];

你在第一个阵列中看到了什么?它为null,因为它未初始化。您所要做的就是像对array2一样初始化数组。

希望这有帮助, 彼得

*抱歉格式化,stackoverflow javascript以某种方式阻止了我。