方法命名取决于返回类型

时间:2010-10-27 08:03:45

标签: c# oop

试图避免Tell-not-ask,我想在调用方法之前将bool属性组合成一个返回bool的新方法。

我尝试遵循该模式,如果某个方法无法执行其名称所隐含的操作,则会抛出异常。例如,如果SendMail无法发送邮件,则会抛出异常。

我希望这个特殊的方法返回一个bool来表示成功。我在考虑是否应该将名称更改为类似TrySendMail的东西,或许用bool返回类型查看方法签名应该足够了吗?

5 个答案:

答案 0 :(得分:5)

命名方法TrySendMail似乎是一个不太糟糕的方法。但是,与您的整体命名方案一致是最重要的事情。

答案 1 :(得分:5)

整个TryWhatever命名模式似乎是来自Microsoft的一个相当新的事情,但是行为(尝试做某事,如果失败则抛出,如果没有则返回有意义的强类型值)已经存在很长一段时间。

理论上,如果方法采用接收结果的ref参数并返回bool,则应使用TryWhatever。如果方法失败,则返回false。如果成功,则结果存储在ref参数中(始终是最后一个参数),并返回true。

您可以使用DateTime.TryParse方法作为示例。如果方法与该模式不匹配,则它不是此命名约定的候选者。

对我来说,使用此约定时,一致性是关键。不要让开发人员感到惊讶。我们中的一些人是非常可怕的人!

答案 2 :(得分:1)

如您所知,TrySomething模式在几种.NET BCL方法(各种TryParse方法)中使用,并且人们习惯于它,所以它不应该让任何人感到惊讶。

如果你的方法的签名只是bool TrySendMail(Mail mail),那么它应该是非常明显的。我宁愿看到这样的签名:

bool WasMailSentSuccessfully(Mail mail);

因为后一种方法不太清楚该方法实际发送邮件。因此,如果您使用Try前缀,那么您正在做出正确的命名选择。就我而言。

另一方面,当我看到Try前缀时,我通常希望在参数列表中看到out关键字,这将遵循以下约定:

bool TrySendMail(Mail mail, out string error);

用作:

string error = null;
if (!TrySendMail(mail, out error))
   Console.WriteLine(error);

这个惯例虽然很常见,但从OOP的角度来看实际上相当丑陋。它基本上是一个返回两个值的方法,而不是通过引用传递其中一个参数,一个适当的OOP方法是将所有返回值包装在一个新类中。

所以我更喜欢这样的东西:

SendResult SendMail(Mail mail);

然后你可以像这样使用它:

SendResult sendResult = SendMail(mail);
if (!sendResult.Success)
    Console.WriteLine(sendResult.Value);

其中SendResult可能是这样的:

public class SendResult : ActionResult<string>
{ ... }

public class ActionResult<T>
{
    public bool Success { get; private set; }
    public T Value { get; private set; }
    public ActionResult<T>(bool success, T value)
    {
        Success = success;
        Value = value;
    }
}

好处是以后添加一堆额外的返回值不会改变方法的签名。

答案 3 :(得分:0)

我记得在Code Complete 2中阅读了一篇关于命名约定的文章(尽管我记不清楚),除了尝试保持它们的通用性以便它们可以用于多个应用程序时它们都应该具有一定的一致性。在这种情况下,将其命名为“SendMail”使其保持直截了当,并允许您轻松地重复使用它而无需用户担心实现细节,这显然是它的作用。

将返回类型设置为布尔值应该确保该方法适用于成功/失败操作,使“尝试”部分变得多余。

private bool SendMail()
   {
       try
       {
         //Send mail
         return true;
       } 
       catch()
       {
          //Handle exception
       }
       return false;
    }

如果您要为方法添加XML标头,您甚至可以添加一个解释,说明当您尝试通过IntelliSense调用它时该方法的作用。

答案 4 :(得分:0)

小心例外。例如,如果传递给SendMail的地址格式错误,我认为抛出异常是不合适的。异常是针对异常行为,并且我认为不发送邮件是因为地址形成不良是预期的行为,并非例外。如果没有发送邮件而不是抛出异常,我肯定会返回错误(也许是字符串原因)。抛出异常并不仅仅是缓慢的,而是意味着堆栈被解开,因此必须担心将所有内容保持在良好的状态。