尝试一起工作的2个实例类的空引用

时间:2017-07-16 16:26:06

标签: c# instance nullreferenceexception

class Program
{
    static void Main(string[] args)
    {
        Worker worker = new Worker();
        worker.Start();

        Console.ReadLine();
    }
}

工人阶级

    public Worker()
    {

    }

    public Navigator Navigator;
    public Scraper Scraper;

    public void ResetVariables()
    {
        Navigator = new Navigator(this);
        Scraper = new Scraper(this);
    }

    public void Start()
    {
        ResetVariables();
        Navigator.SetHtml();
    }

导航器类

    private Worker Worker;
    private Scraper Scraper;

    public string Html;

    public Navigator()
    {

    }

    public Navigator(Worker worker)
    {
        Worker = worker;
        Scraper = worker.Scraper;
    }

    public void SetHtml()
    {
        Html = "navigator has changed its html";
        Scraper.ReadHtmlFromNavigator(); //CAUSES NULL REFERENCE IF CALLED INISIDE THIS METHOD
    }

刮刀类

    private Worker Worker;
    private Navigator Navigator;

    public Scraper()
    {

    }

    public Scraper(Worker worker)
    {
        Worker = worker;
        Navigator = Worker.Navigator;
    }

    public void ReadHtmlFromNavigator()
    {
        Console.WriteLine("scraper reading html from navigator: " + Navigator.Html);
    }

当我从导航器本身调用Scraper.ReadHtmlFromNavigator()时,我得到一个空引用,但如果我从worker类调用它,它可以正常工作:

public void Start()
    {
        ResetVariables();
        Navigator.SetHtml();
        Scraper.ReadHtmlFromNavigator();
    }

我得到了输出:

scraper reading html from navigator: navigator has changed its html

2 个答案:

答案 0 :(得分:0)

快速回答 - 不要在Scrapper中存储对Navigator的引用,也不要在Navigator中存储对Scrapper的引用。改为使用对工人的引用。

在方法SetHtml中调用Worker.Scraper.ReadHtmlFromNavigator()而不是Scraper.ReadHtmlFromNavigator()

更新: 如果您不想每次都输入Woker.XXX,可以创建一些快捷方式:

private Navigator Navigator { get { return Worker.Navigator; } }
private Navigator Scrapper{ get { return Worker.Scrapper; } }

答案 1 :(得分:0)

在使用刮刀之前,您首先要构建一个新的导航器:

public void ResetVariables()
{
    Navigator = new Navigator(this);
    Scraper = new Scraper(this);
}

因此,您的导航器构造函数将其 scraper 变量设置为尚未存在的worker.scraper。

Simpy改变顺序你应该没事:

public void ResetVariables()
{
    Scraper = new Scraper(this);
    Navigator = new Navigator(this);
}

但是,一般情况下,请重新考虑如何设置应用程序。这种无证的强制性序列会产生问题并且是代码味道。