out 参数的默认值

Default values for out parameters

提问人:Andrew Truckle 提问时间:9/9/2023 最后编辑:Andrew Truckle 更新时间:9/10/2023 访问量:56

问:

以这个函数为例:

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);
    }
}

它有两个参数。我希望在块分配默认值。但是系统会标记它们未初始化。outtry

enter image description here

所以我把它们移到了函数的顶部。但是构造函数可能会通过异常,这就是为什么我想在块中声明它。DateTimetry

解决这个难题的正确方法是什么?

C# 输出

评论

0赞 Bagus Tesa 9/9/2023
“但是系统标记它们没有初始化。- 哪个系统?第三方代码分析器?
3赞 Daniel A. White 9/9/2023
只需分配,然后稍后再分配default
1赞 JLRishe 9/9/2023
正如我已经说过的,永远不会抛出例外。没有什么可抓的。date = new DateTime(1900, 1, 1);
3赞 Dmitry Bychenko 9/9/2023
如果抛出异常,则 out 参数将被取消分配,这就是编译器抱怨的原因。XDocument.Load(talksdatabase);
1赞 Progman 9/9/2023
@AndrewTruckle 当块内的任何异常在默认值之前抛出并分配时(例如何时抛出异常)时,应该分配哪个值?datehasMediatrydatehasMediaXDocument.Load()

答:

3赞 Lynn 9/10/2023 #1

如果在 -block 中设置了 out 参数,则可能会遇到代码在设置 out 参数之前抛出的情况。在这种情况下,代码将继续在 catch 块中执行。如果您也将它们设置在那里,或者抛出异常,那就没问题了。但是,由于您不这样做,您将在不设置 out 参数的情况下从函数返回。这是不允许的。 为了更清楚起见,请参阅我添加到您的代码中的注释:try

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.
}