我应该抛出异常还是返回false?

3
我正在使用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吗?还是应该抛出异常?
在这种情况下,我的客户将是其他开发人员。

1
由于它返回一个布尔值,所以不需要抛出异常,只需返回false即可。 - preciousbetine
3个回答

3

如我们之前约定的那样,每当你使用TryXXXX模式时,你的方法必须始终成功,并返回实际的成功结果作为布尔值。如果你想抛出异常,只需从方法名中删除"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;
}

我不建议将整个函数用 try..catch 包裹起来。因为如果 this.service.Add 行抛出了一些意料之外的异常,那么这个异常就会被吞掉。 - Fabio
1
@Fabio,这就是TryXXXX模式的全部意义——无论出现任何问题,甚至整个系统崩溃,都不要抛出异常!而潜在的异常也不会被隐藏——如果Add方法中出现任何异常,函数将返回false。 - Max

0
我使用这个场景: 我有一个类,所有服务都返回这个类,命名为(例如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>();
}

在您的表单中,检查消息是否为空或空白,如果是,则没有错误......您可以自定义它...

0

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

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

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

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

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

作为开发人员,我希望尽可能快地收到反馈,以便在出错时及早发现。在应用程序启动期间(通常是服务注册阶段),抛出异常将是最快的反馈方式。除非您使用带有约束条件的泛型,在编译时提供早期反馈。
如果开发人员没有失败注册的逻辑,则不返回任何内容,但使用描述性消息抛出自定义异常。
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);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接