Search code examples
c#out

Default values for out parameters


Take this function:

public void GetOutlineDateAndMediaClassification(string talksdatabase, int talknumber, out DateTime date, out bool hasMedia)
{
    date = new DateTime(1900, 1, 1);
    hasMedia = false;

    try
    {
        XDocument doc = XDocument.Load(talksdatabase);
        var ptInfo = doc
                        .Descendants("PublicTalk")
                        .Where(p => p.Attribute("Number").Value == talknumber.ToString()).First();

        if (ptInfo != null)
        {
            date = DateTime.Parse(ptInfo.Attribute("IssueDate").Value).Date;
            hasMedia = Convert.ToBoolean(ptInfo.Attribute("Media").Value);
        }
    }
    catch (Exception ex)
    {
        SimpleLog.Log(ex);
    }
}

It has two out parameters. I wanted the default values to be assigned inside the try block. But the system flags they are not initialized.

enter image description here

So I moved them to the top of the function. But the DateTime constructor might through an exception, which is why I wanted to declare it in the try block.

What's the right way to deal with this conundrum?


Solution

  • If the out parameters are set inside the try-block, you could have a situation where your code throws before you set the out parameters. In that case the code will continue executing in the catch block. This would be fine if you set them there as well, or throw an Exception. But since you don't, you will return from the function without having set the out parameters. That is not allowed. Please see the comments I have added to your code for more clarity:

    public void GetOutlineDateAndMediaClassification(string talksdatabase, int talknumber, out DateTime date, out bool hasMedia)
    {
        try
        {
            XDocument doc = XDocument.Load(talksdatabase); // (1) Assume Document.Load(talksdatabase) throws an exception. Note that you have not set date or hasMedia yet.
            var ptInfo = doc
                            .Descendants("PublicTalk")
                            .Where(p => p.Attribute("Number").Value == talknumber.ToString()).First();
    
            date = new DateTime(1900, 1, 1);
            hasMedia = false;
    
            if (ptInfo != null)
            {
                date = DateTime.Parse(ptInfo.Attribute("IssueDate").Value).Date;
                hasMedia = Convert.ToBoolean(ptInfo.Attribute("Media").Value);
            }
        }
        catch (Exception ex)
        {
            // (2) Your code will continue here after (1) without executing the rest of the try-block. date and hasMedia still have not been set. 
            SimpleLog.Log(ex);
        }
    
        // (3) There is no more code to execute but date and hasMedia are not set. This is invalid.
    }