输出参数有什么问题?

时间:2009-09-16 17:31:13

标签: c# sql vba vb6

在SQL和C#中,我从未真正喜欢输出参数。我从未在VB6中传递参数ByRef。关于计算副作用以完成某些事情的事情让我感到困扰。

我知道他们是一种无法从函数返回多个结果的方法,但SQL中的行集或C#和VB中的复杂数据类型也同样适用,并且对我来说似乎更自我记录。 / p>

我的想法有什么问题,还是来自权威人士的资源支持我?你个人对此有何看法以及为什么?对于想要设计输出参数可能会说服他们使用不同结构的同事,我能说些什么呢?

编辑:有趣的转向 - 我问这个问题的输出参数是用来代替返回值。当返回值为“ERROR”时,调用者应该将其作为例外处理。我这样做但对这个想法并不满意。一位同事没有被告知有必要处理这种情况,因此,由于程序无声地失败,大量资金已经丢失!

11 个答案:

答案 0 :(得分:28)

输出参数可能是代码气味,表明您的方法做得太多了。如果您需要返回多个值,则该方法可能不止一件事。如果数据紧密相关,那么它可能会从包含两个值的类中受益。

当然,情况并非如此,但我发现情况通常如此。

换句话说,我认为你应该避免它们。

答案 1 :(得分:20)

他们有自己的位置。 Int32.TryParse方法是有效使用out参数的一个很好的例子。

bool result = Int32.TryParse(value, out number);
if (result)
{
    Console.WriteLine("Converted '{0}' to {1}.", value, number);         
}

答案 2 :(得分:11)

Bob Martin写了关于这个清洁代码的文章。输出参数打破了函数的基本思想。

output = someMethod(input)

答案 3 :(得分:1)

我认为它们对于在同一个SQL命令中获取新插入行的ID很有用,但我认为我没有将它们用于其他许多行。

答案 4 :(得分:1)

我也很少看到out / ref参数的使用,尽管在SQL中,有时通过参数传递值比使用结果集更容易(这需要使用DataReader等)。 p>

虽然幸运的是,我今天在C#中创建了一个这样罕见的功能。它验证了一个类似于表的数据结构,并返回了它中的行数和列数(计算起来很棘手,因为该表可能有HTML中的rowspans / colspans)。在这种情况下,两个值的计算同时进行。将它分成两个函数会导致代码,内存和CPU时间要求翻倍。只为这一个函数创建一个自定义类型返回对我来说似乎有点过分了。

所以 - 有时候它们是最好的东西,但大多数情况下你可以在没有它们的情况下做得很好。

答案 5 :(得分:1)

SQL Server 2005及更高版本中的OUTPUT子句是获取受DML语句影响的行的任何字段值的重要一步。我认为有很多情况会消除输出参数。

在VB6中,ByRef参数适合传递ADO对象。

除了我想到的两个具体案例之外,我倾向于避免使用它们。

答案 6 :(得分:1)

仅限SQL ...

存储过程输出参数很有用。

  1. 假设您需要一个值。你是“创建#table,插入... exec,选择@var =”。或者使用输出参数?

  2. 对于客户端调用,输出参数比处理记录集要快得多。

  3. 使用RETURN值仅限于有符号整数。

  4. 更容易重复使用(例如安全检查帮助程序)

  5. 同时使用:recordsets = data,输出参数= status / messages / rowcount等

  6. 存储过程记录集输出不能像UDF或客户端代码那样强类型化

  7. 您不能总是使用UDF(例如,在上面的安全检查期间记录)

  8. 但是,只要您通常不使用相同的参数进行输入和输出,那么在SQL完全更改之前,您的选项将受到限制。说这个,我有一个案例,我使用参数进出值,但我有充分的理由。

答案 7 :(得分:1)

我的两分钱:
我同意输出参数是一种有关的做法。 VBA通常由非常新的编程人员维护,如果维护代码的人没有注意到参数是ByRef,他们可能会引入一些严重的逻辑错误。它也倾向于破坏Property / Function / Sub范例 使用输出参数的另一个原因是不好的做法是,如果您真的需要返回多个值,那么您可能应该在数据结构中使用这些值,例如类或用户定义类型。
然而,他们可以解决一些问题。 VB5(因此Office 97的VBA)不允许函数返回数组。这意味着返回或更改数组的任何内容都必须通过“out”参数来完成。在VB6中已添加此功能,但VB6仍然强制数组参数为引用(以防止在内存中过度复制)。现在你可以从改变数组的函数返回一个值。但它只是一个慢的头发(由于杂技在幕后进行);它也会让新手们误以为数组输入不会被改变(只有当某人特意以这种方式构建它时才会这样)。所以我发现如果我有一个改变数组的函数,它可以减少混淆,只使用一个sub而不是一个函数(它也会更快一点)。
另一种可能的情况是,如果您要维护代码,并且希望在不破坏界面的情况下添加输出值,则可以添加可选的out参数,并确信您不会破坏任何旧代码。这不是一个好习惯,但是如果有人想要修复现在并且你没有时间以“正确的方式”进行重组并重新构建所有内容,这可能是您工具箱的一个方便的补充。
但是,如果您从头开始开发并且需要返回多个值,则应考虑:
 1.打破功能。
 2.返回UDT  3.返回班级。

答案 8 :(得分:0)

我一般都不会使用它们,我认为它们很容易混淆,而且容易滥用。我们偶尔会使用ref参数,但这更多地与传入结构有关,而不是让它们回来。

答案 9 :(得分:0)

你的意见对我来说听起来很合理。

输出参数的另一个缺点是将结果从一个函数传递到另一个函数所需的额外代码。您必须声明变量,调用函数以获取其值,然后将值传递给另一个函数。你不能只嵌套函数调用。这使得代码读取非常紧迫,而不是声明性的。

答案 10 :(得分:0)

C ++ 0x正在获取元组,这是一种类似于匿名结构的东西,其成员可以通过索引访问。 C ++程序员将能够将多个值打包到其中一个并返回它。 C#有这样的东西吗?它可能会返回一个数组吗?但是,输出参数有点尴尬和不清楚。