我应该抛出异常还是 return false?

Should I throw an exception or return false?

我正在使用 TDD 在 C# 中开发一个简单的服务定位器。

目前,我创建了一个 TryAddService 方法,如下所示:

    public bool TryAddService(Type type, object service)
    {
        if (service == null)
        {
            return false;
        }

        if (this.services.ContainsKey(type))
        {
            return false;
        }

        if (!type.IsAssignableFrom(service.GetType()))
        {
            return false;
        }

        this.services.Add(type, service);

        return true;
    }

我的问题是,在所有这些情况下我都应该返回 false 吗?还是应该抛出异常?

在这种情况下,我的客户将是其他开发人员。

我使用这个场景: 我有一个 class 所有服务 return 这个 class 命名(例如 MyReturn)

public sealed class MyReturn<TEntity> : IDisposable
{
    public string Message { get; set; }
    public TEntity Entity { get; set; }
    public string SysException { get; set; }
    // and etc...
    public void Dispose() {}
}

现在您的服务:

public MyReturn <bool> TryAddService(Type type, object service)
{
    if (service == null)
        return new MyReturn <bool> {Message = "Your messgage"};
    //and etc...
    return new MyReturn <bool>();
}

在您的表单中检查 Message ,如果为 null 或为空,则没有错误.... 您可以自定义它...

根据非正式约定,无论何时使用 TryXXXX 模式,您的方法都必须始终成功,但 return 实际成功结果为布尔值。如果你想抛出异常,那么只需从你的方法名称中删除 "try" 单词。

最重要的是,如果您遵循 TryXXXX 模式,我建议您添加一个 try-catch 块,以确保您的方法真正始终成功:

public bool TryAddService(Type type, object service)
{
  if (service == null)
  {
    return false;
  }

  if (this.services.ContainsKey(type))
  {
    return false;
  }

  if (!type.IsAssignableFrom(service.GetType()))
  {
    return false;
  }

  try
  {
    this.services.Add(type, service);
  }
  catch
  {
    return false;
  }

  return true;
}

My customers in this scenario would be other developers.

您是否希望 class 的消费者有条件地注册类型?

if (TryAddService(typeof(IService), new Service1()))
{
    // Added successfully - what to do next
}
else
{
    // What here? Try another service?
}

或者开发人员将只注册他们需要的实现,并依赖于 TryAddService 将在应用程序启动期间抛出异常这一事实。

TryAddService(typeof(IService), new Service1());

作为开发人员,如果我做错了什么,我希望尽快收到反馈。在应用程序启动期间抛出异常(通常在此处完成服务注册)将是最快的反馈。除非您将使用带有约束的泛型,这将在编译时及早提供反馈。

如果开发者没有注册失败的逻辑,那么return什么都不做,但会抛出带有描述性消息的自定义异常

public void TryAddService(Type type, object service)
{
    if (service == null)
    {
        throw new RegisterServiceException($"Can not register null for type '{type.FullName}'");
    }

    if (this.services.ContainsKey(type))
    {
        throw new RegisterServiceException($"Service for type '{type.FullName}' already registerd.");
    }

    if (!type.IsAssignableFrom(service.GetType()))
    {
        throw new RegisterServiceException($"Type '{type.FullName}' should be assignable from service of type '{service.GetType().FullName}'");
    }

    this.services.Add(type, service);
}