C# C语言中out参数的正确使用#

C# C语言中out参数的正确使用#,c#,out,C#,Out,编辑:我知道这通常是不做的,并且是在坏的实践线上,但是在这个特定的使用案例中,我的手是被迫的。我的另一个选择(正如我在本例中看到的)是通过我的单例(未显示)发送事件并订阅它——但这似乎也是“糟糕的形式” 我有一个关于out参数的问题,然后我把它扔进我的代码中,把事情搞砸了 class myExam { private bool faulted = true; public myExam(string demo) { .... } public myExam(strin

编辑:我知道这通常是不做的,并且是在坏的实践线上,但是在这个特定的使用案例中,我的手是被迫的。我的另一个选择(正如我在本例中看到的)是通过我的单例(未显示)发送事件并订阅它——但这似乎也是“糟糕的形式”

我有一个关于out参数的问题,然后我把它扔进我的代码中,把事情搞砸了

class myExam
{
    private bool faulted = true;

    public myExam(string demo) { .... }

    public myExam(string one, string two, string three) { .... }

    public myExam(string demo, out bool success)
    {
        try
        {
            // bool to hard kill processing
            while(faulted)
            {

                // do stuff

                // no fault, out true
                success = faulted;

                // break loop
                faulted = false;

            }

        }
        catch
        {
            // fault, set faulted, return out false
            faulted = false;
            success = faulted;
            // Correct? ^
        }
    }
}

我的问题是。A) 如果没有问题,在catch和B)try中返回的方法正确吗?我的假设是,我已经正确地阅读/理解了所有内容,但在把事情搞砸之前,我想知道是否可以检查一下我的逻辑。idk如果这个问题问得不好或者不正确,那么答案就是“是”:/

让我们回答你的问题,这样我们就可以结束这个问题了

A)这是返回渔获物的正确方法吗

正如我在一篇评论中所说,获取
out
参数以“返回”值的正确方法是为其赋值。因此,是的,为catch中的
success
参数指定一个值(而不是进一步更改它)将使构造函数在该参数中“返回”该值

B)在try中,如果没有问题,该输出是否为真?

是的,前提是您确保将
success
设置在其他地方,也许从开始。否则,编译器会认为您在所有情况下都未能设置参数,并对此进行投诉

(代码如图所示)


如果您不能或不会按照注释中的建议更改代码以删除out参数,并且循环只是为了使成功为真,我将简化代码:

public myExam(string demo, out bool success)
{
    success = false;
    try
    {
        // do stuff

        // no fault, out true
        success = true;
    }
    catch
    {
    }
}

然而,我可能也会确保只处理您知道可能发生的异常。这样的“捕获所有内容”块在很多级别上都是错误的,因此这不是一个好的建议。

在方法返回之前必须分配Out参数,因此所有可能的路径都必须设置
success
的值。您可能需要添加一个
finally
子句并在其中设置值,或者您可以将其设置为默认值以开始,然后继续执行方法的其余部分

如果我将您的代码粘贴到linqpad中,实际上会出现编译错误:

The out parameter 'success' must be assigned to before control leaves the current method

另一方面,您使用的
faulted
有点奇怪,因为当没有故障时
success
false
,建议略有不同,但为什么不在对象上设置LoadSuccess属性,例如

public class MyExam {
   public bool LoadSuccess { get; private set; }

   public MyExam() {
      //If not loadeded happily set the LoadSuccess property in here.
   }
}
这使得您的代码比构造函数中的out参数稍微少一些意外


上面的代码将按照您构建代码的方式进行处理,但对我来说,如果出现错误,那么应该在调用代码中抛出并处理异常


举一个例子,下面的另一个开发人员调用此代码,但在构造函数调用之后不计算“success”布尔值。然后会发生什么-代码会继续快乐吗?可能没有。

我想你还不清楚
try-catch
是如何工作的。我建议你看一些例子。这是一个毫无意义的评论-有什么问题吗-为了简单起见,我删除了我的错误句柄。是的,我知道一旦它掉到catch中,它将打破循环,但我仍然需要在传递它之前更改bool,或者我理解为问题:循环的目的是什么,因为不管怎样,在1次迭代之后,您似乎就可以突破它了。在构造函数中有一个
out
参数,这似乎有点奇怪。这个问题表明我不是唯一一个有这种感觉的人。假设
out
是适合您使用的设计选择,那么我建议更简单的方法是添加一个
finally
块来设置
success=faulted。这就是循环的原因-不会出错但有其他错误的错误仍然可以返回true(即那些错误会做其他事情),而在该捕获中,它们完全是fubar,需要抛出false。但是我会考虑你的建议——我可能对“硬杀戮”方面考虑得太多了。@alykins我在我的问题中修正了两件事,特别是我改变了B)中“是”的条件,因为你会得到一个编译器错误,如图所示,除非你确保在所有情况下都设置了
success
(例如,在构造函数的开头将其设置为false)。我也对下面的代码做了一些修改,以达到同样的效果。谢谢你指出这一点。我错过了“如果”它在这方面失败了。奇怪的是——我想这可能是在构造函数上通常不这样做的一个原因——我想当我尝试调用它时,它会在另一端抛出一个未经处理的异常。是的,我在Lasse之后才看到这个指出它-我不会在捕获之前分配它,所以它对你来说没有价值问题-我在记事本中写得很快-linqpad像一个迷你编译器吗?我以前从未使用过它,我认为它只是用于LINQ数据库查询(我不经常使用LINQ,努力更好地理解/学习它)Linqpad有点像一个记事本编译器,它允许你编译和运行代码片段。非常方便的工具,特别是对于学习C#。你可以在控制台应用程序中做大多数事情。这实际上会完全解决我的问题-非常感谢你的不同观点。我现在可以放弃这个想法了。好主意!我太习惯了/focu我习惯于只看到对象被包装起来,并且它的所有属性都是私有的,我没有想到会这样做。