我正在查看我继承的一些代码,如果我喜欢一些代码,我就无法决定。
基本上,有一种方法如下所示:
bool Connect(connection parameters){...}
如果成功连接则返回true,否则返回false。
我过去曾编写过这样的代码,但是现在,当我看到这种方法时,由于种种原因,我不喜欢它。
很容易编写代码,只是忽略返回的值,或者没有意识到它会返回一个值。
无法返回错误消息。
检查方法的返回并不是很好看:
if(!Connect(...)){....}
我可以重写代码以在未成功连接时抛出异常,但我不认为这是一种特殊情况。相反,我正在考虑重构代码如下:
void Connect(Connection Parameters, out bool successful, out string errorMessage){...}
我喜欢其他开发人员必须提供成功和错误字符串,以便他们知道该方法有错误条件,我可以知道返回消息
有人对此事有任何想法吗?
由于 -Matt
答案 0 :(得分:12)
我会选择异常而非out
参数。如果您希望班级的消费者关心,请让他们关注异常,或者让他们独自一人。通过使用out参数,如果他们没有 来关注它们,那么他们只会让他们的生活变得更加不方便。还要考虑一下,如果你的函数已经存在,那么如果更改签名(而不是提供额外的重载),则会引入重大更改。
程序员期望在错误情况下出现异常,特别是在C#等语言中。我们受过训练。
答案 1 :(得分:3)
我只有一个意见,所以请考虑它的价值。
这样一个名为“Connect”的方法就是一个命令。这就像给一个士兵,“跳”或“拍”。你不希望士兵报告,除非他无法完成订单,这将是一件罕见的事情。
因此,我倾向于没有这种方法的返回值,但如果有可能在常规使用该方法时会出现故障,那么我构建第二个方法,名为TryXYZ,返回一个bool,如果有必要的话,向我提供任何XYZ作为输出参数的结果。
这遵循.NET BCL中各种数字类型的Parse方法所规定的标准。
所以在你的情况下,我可能会:
void Connect(connection parameters);
bool TryConnect(connection parameters, out status);
好消息是,如果正确构建TryConnect方法,Connect变得非常容易。
示例:
public bool TryConnect(string connectionString, out ConnectionStatus status)
{
... try to connect
... set status, and return true/false
}
public void Connect(string connectionString)
{
ConnectionStatus status;
if (!TryConnect(connectionString, out status))
switch (status)
{
case ConnectionStatus.HostNotFound:
throw new HostNameNotFoundException();
...
}
}
我不希望我的订单没有完成,但从某种意义上说,我可能会明确表示。
答案 2 :(得分:1)
我看到你的观点,但要加上我的2c。
我通常不是输出参数的粉丝。如果需要从函数中返回多个值,请重新评估函数正在执行的操作,在大多数情况下,多个返回值表示方法执行的操作太多。在你的情况下,它是合法的,将从你的connect方法返回一个复杂的类型(超出一个简单的布尔值)。
我赞成从connect方法返回一个自定义类型,它存储所有相关信息而不是多个输出参数。考虑未来的可扩展性,如果您需要在未来包含更多信息,该怎么办?添加额外的输出参数是一个重大改变
此外,我倾向于不同意强制用户为所有状态数据提供内存分配。有时我不关心成功消息(也许我只关心它是否错误)在这种情况下必须通过两个输出参数是一种痛苦。
我同意,但是检查发布的初始方法的返回值并不理想。
答案 3 :(得分:1)
我不介意Connect函数返回一个布尔值,我不是输出参数的忠实粉丝。如果函数没有返回连接状态,你可能不得不写一个IsConnected函数/属性(取决于你的样式),以允许某人检查它,这样就省了一步。
就预期而言,让异常被调用代码捕获,这将迫使调用者关心。 :)
答案 4 :(得分:1)
我同意不建立联系(在大多数情况下)不应被视为特殊情况。但是,强制用户为错误字符串等提供参数也不是很好。其他可能的解决方案:
答案 5 :(得分:0)
不确定这是否比重构代码更好,但希望这可以给你另一个想法。
对于我的项目,我创建了一个返回最后一条错误消息的方法。
string Error = '';
bool Connect(connection parameters)
{
// do my connection here
// if there's an error set string variable Error
// This way you can set different error message depending on what you're doing
}
string lastErrorMessage(){
// return Error string
}
这样你可以这样做:
if(!connect(...))
{
string message = lastErrorMessage();
// Then do what you need here.
}
这可能不是最好的方法,但应该对你有所帮助:)。