【问题标题】:NullReferenceException for Public class member公共类成员的 NullReferenceException
【发布时间】:2013-08-26 12:15:33
【问题描述】:

以下代码在调用 GetDepAirport() 方法时抛出“'System.NullReferenceException' 类型的未处理异常发生在...”。

    public WYPT GetDepAirport()
    {
        Console.WriteLine("Retrieving Airport in GetDepApt()");
        Console.WriteLine("Departure Airport is {0}", Dep.Ident);
        return Dep;
    }

    public void SetDepAirport(String ident)
    {
        Console.WriteLine("Setting Airport with ident {0}, ident");
        Dep = FetchDBAirport(ident);
        Console.WriteLine("WYPT Dep is set to {0}", Dep.Ident);
    }

输出是:

Setting Airport with ident KABQ
WYPT Dep is set to KABQ
Retrieving Airport in GetDepApt()

随之而来的是一系列异常。当从 GetDepAirport() 方法调用时,我无法弄清楚为什么 Dep(已声明为公共)返回为 null。这两种方法都是从同一个类中的一个单独方法中调用的。

声明在类的顶部:

class FlightPlan
{
   //Init Pg.1 data
    public WYPT Dep, Dest, Altn;

对 set 的调用来自不同的类:

FlightPlan FPlan = new FlightPlan(); 
FPlan.SetDepAirport(Dep);

稍后会调用 Get:

    public void GetFPlan()
    {
        for (int i = 0; i < 14; i++)
        {
            Waypoint[i] = new WYPT();
        }
        Waypoint[0] = GetDepAirport();
        Waypoint[1] = DISCON;

同一个 FlightPlan 类中的 FetchDBAirport 方法

private WYPT FetchDBAirport(String airport)
    {
        WYPT Airport = new WYPT();

        String databasepath = "C:\\Users\\Family\\documents\\visual studio 2012\\Projects\\FMST\\FMST\\Database\\NavData.mdf";
        SqlConnection myConnection = new SqlConnection("Data Source=(LocalDB)\\v11.0;AttachDbFilename=" + databasepath + ";Integrated Security=True");
        try
        {
            myConnection.Open();
            SqlCommand cmd = myConnection.CreateCommand();
            cmd.CommandText = "SELECT * FROM Airports WHERE Ident='" + airport + "';";
            SqlDataReader rdr = cmd.ExecuteReader();
            rdr.Read();

            Airport.Ident = (String)rdr.GetValue(0);
            Airport.Lat = (decimal)rdr.GetValue(2);
            Airport.Lon = (decimal)rdr.GetValue(3);
            Airport.Elev = (decimal)rdr.GetValue(4);

            myConnection.Close();
            return Airport;
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString() + "Happy Face");
            String ErrorMsg = "NOT FOUND";
            Airport.Ident = ErrorMsg;
            return Airport;
        }

【问题讨论】:

  • 您没有向我们展示您在何处或如何声明它。
  • Dep 从未在提供的代码中设置。我们需要更多信息。
  • 可能是 FetchDPAirport(ident); 返回 null。
  • 看起来在调用方法中调用 SetDepAirport 和调用 GetDepAirport 之间的某个地方将 Dep 设置为 null。我们需要查看调用的方法。
  • 我以为你说'这两种方法都是从同一个类中的一个单独方法中调用的'。你能包括所有相关的代码吗?在 Set 和 Get 调用之间一定发生了什么事。

标签: c#


【解决方案1】:

在 GetDepAirport 中唯一可能返回 NullReferenceException 的部分代码是 Dep.IdentDepIdent 可以为空。如果您为这两个都添加空检查,则该方法将运行良好。

至于为什么其中一个为空,可能是因为:

  • 在致电GetDepAirport之前,您还没有致电SetDepAirport
  • FetchDBAirport 要么返回 null,要么返回 Dep 实例,其中 Ident 为 null。
  • 调用 GetDepAirport 的代码正在其他地方改变 Dep 的值
  • Dep 未正确存储值 - 因此可能是属性定义中的问题

【讨论】:

  • 我先设置机场,并使用 Console.WriteLine 来验证数据是从数据库中设置的(获取...)。我正在调查你的最后两颗子弹,因为我在这颗子弹上非常摸不着头脑。
  • 我认为上面列出的四个项目符号在逻辑上是一组完整的原因 - 它一定是其中之一!
  • 我发现问题与范围有关。一旦调用 SetDepAirport() 方法的方法结束,Dep 变量就会变回 null。
  • 问题比这更简单。我将 Dep 变量更改为静态,一切都很好。现在像冠军一样工作。
  • 我很高兴它可以工作,但要指出的是,通常你应该避免像这样静态存储状态,因为一个字段将在它所在类的所有实例之间共享。如果一个实例类的值更改了值,然后它也将应用于该类的所有其他实例。它应该可以作为实例(非静态)字段正常工作。
猜你喜欢
  • 2012-09-17
  • 1970-01-01
  • 2017-12-28
  • 1970-01-01
  • 2015-07-11
  • 2013-10-10
  • 1970-01-01
  • 1970-01-01
  • 2014-06-03
相关资源
最近更新 更多