Declare Selenium webdriver as nullable instance variable in C# CS8618

51 Views Asked by At

I would like to get rid of the CS8618 warning in my C# code.

var scrapper = new Scrapper();
scrapper.Run();

Attempt 1, KO:

class Scrapper
{
    private IWebDriver driver; // <= the warning applies to the "driver" instance variable
    private const string url = "https://www.google.com/";
    private const string rejectCookiesButtonXPath = "//*[@id=\"W0wltc\"]/div";

    private void InitWebDriver()
    {
        driver = new ChromeDriver();
        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
    }

    public void Run()
    {
        InitWebDriver();
        driver.Navigate().GoToUrl(url);
        driver.FindElement(By.XPath(rejectCookiesButtonXPath)).Click();
    }
}

Attempt 2, creating a constructor, KO:

class Scrapper
{
    private IWebDriver driver;
    private const string url = "https://www.google.com/";
    private const string rejectCookiesButtonXPath = "//*[@id=\"W0wltc\"]/div";

    private void InitWebDriver()
    {
        driver = new ChromeDriver();
        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
    }

    public Scrapper() // <= the warning applies now to the constructor
    {
        InitWebDriver();
    }

    public void Run()
    {
        driver.Navigate().GoToUrl(url);
        driver.FindElement(By.XPath(rejectCookiesButtonXPath)).Click();
    }
}

Attempt 3:

If I explicitely use the instructions of InitWebDriver() method in the constructor, it is OK as the warning disappears, but I would like to be free of organizing the code as I want.

class Scrapper
{
    private IWebDriver driver;
    private const string url = "https://www.google.com/";
    private const string rejectCookiesButtonXPath = "//*[@id=\"W0wltc\"]/div";

    public Scrapper() // <= the warning disappears
    {
        driver = new ChromeDriver();
        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
    }

    public void Run()
    {
        driver.Navigate().GoToUrl(url);
        driver.FindElement(By.XPath(rejectCookiesButtonXPath)).Click();
    }
}

I also know that I could use the question mark nullable symbol...

private IWebDriver? driver;

... but then I also should use "driver!" (with the exclamation mark) each time I use the driver.

What am I missing please?

Thank you for your help.

1

There are 1 best solutions below

0
Arthur Edgarov On

When working with #nullable directive - it is good to know the attributes used to instruct the compiler how your code works.

class Scrapper
{
    private IWebDriver? driver;

    [MemberNotNull(nameof(driver))] // This attribute indicates that when execution will exit this method the variable `driver` wont be null
    private void InitWebDriver()
    {
        driver = new ChromeDriver();
    }

    public Scrapper()
    {
        InitWebDriver(); // So when you call your init method with that attribute in the constructor - the compiler will not populate any warnings, since you've set the value for the variable.
    }

    public void Run()
    {
        // And now here you do not need to use null forgiving operator, since your var is not null
        driver.Navigate().GoToUrl(url);
        driver.FindElement(By.XPath(rejectCookiesButtonXPath)).Click();
    }
}