我有一个类似...的方法

int f() {
  try {
    int i = process();
    return i;
  } catch(Exception ex) {
    ThrowSpecificFault(ex);
  }
}

这会产生编译器错误,“并非所有代码路径返回值”。但是在我的情况下,抛出特定福特()将始终抛出(适当的)例外。因此,我被迫在结尾处提出回报率,但这很丑陋。

首先,这种模式的目的是因为“ process()”是对外部Web服务的调用,但需要翻译各种不同的异常以匹配客户端的预期接口(我想〜位置模式)。

有什么干净的方法吗?

有帮助吗?

解决方案

我建议你转换 ThrowSpecificFault(ex)throw SpecificFault(ex);这 SpecificFault 方法将返回要抛出的异常对象而不是抛出它。更干净。

这是推荐的模式 微软的指南 (找到文本“使用异常构建器方法”)。

其他提示

现在,返回类型可以是一种类型,也可以是“无返回类型”的“ void”。从理论上讲,我们可以添加第二种特殊返回类型“ Never”,它具有您想要的语义。表达式陈述的终点是由“永不”返回方法组成的呼吁,将被认为是无法达到的,因此,在C#中的每个情况下,“ goto”,“ throw”或“ return”是合法的。 。

现在不太可能将其添加到现在的类型系统中,十年。下次您从头开始设计类型系统时,请记住包含“ Never”类型。

这里的问题是,如果您进入 catch 块IN f() 您的功能将永远不会返回值。这将导致错误,因为您将功能声明为 int 这意味着您告诉编译器您的方法将返回整数。

以下代码将执行您要寻找的内容,并始终返回整数。

int f() {
  int i = 0;
  try {
    i = process();

  } catch(Exception ex) {
    ThrowSpecificFault(ex);
  }
  return i;
}

将返回语句放在函数末尾,您会没事的。

无论您的应用程序经历什么执行路径,确保您的方法始终返回值总是一个好主意。

您可以这样做:

catch (Exception ex)
{
    Exception e = CreateSpecificFault(ex);
    throw e;
}

不。

想象一下 ThrowSpecificFault 在单独的DLL中定义。如果您修改DLL以不引发异常,然后在不重新编译的情况下运行程序,会发生什么?

您有三个选择:

总是返回我,但会预先调理:

int f() {
    int i = 0; // or some other meaningful default
    try {
        i = process();
    } catch(Exception ex) {
        ThrowSpecificFault(ex);
    }
    return i;
}

从该方法中返回例外,并抛出:

int f() {
    try {
        int i = process();
        return i;
    } catch(Exception ex) {
        throw GenerateSpecificFaultException(ex);
    }
}

或创建一个自定义异常类,然后抛出:

int f() {
    try {
        int i = process();
        return i;
    } catch(Exception ex) {
        throw new SpecificFault(ex);
    }
}

怎么样:

int f() {
 int i = -1;
 try {
   i = process();       
 } catch(Exception ex) {
   ThrowSpecificFault(ex);
 }
 return i;
}

是的。

不要指望throwspecificfault()会引发异常。让它返回例外,然后将其扔在这里。

实际上,这也更有意义。您不使用“正常”流程的异常,因此,如果您每次都引发异常,则例外将成为规则。在功能中创建特定的异常,然后将其扔在此处,因为它是此处流的例外。

我想您可以使throwspecificfault返回对象,然后您可以

return ThrowSpecificFault(ex)

否则,您可以将throwsefificfault重写为异常子类型的构造函数,也可以将throwspecificfault放入创建异常但不会抛出它的工厂中。

在您的情况下,这是您的知识不是编译器。现在可以说这种方法肯定会引发一些讨厌的例外。

试试这个

int f() {
  try {
    return process();
  } catch(Exception ex) {
    ThrowSpecificFault(ex);
  }
  return -1;
}

您也可以使用掷键字

int f() {
  try {
    return process();
  } catch(Exception ex) {
    throw ThrowSpecificFault(ex);
  }
}

但是,该方法应返回一些例外,而不是抛出它。

使用Unity.therception清理代码。通过拦截处理,您的代码看起来像这样:

int f() 
{
    // no need to try-catch any more, here or anywhere else...
    int i = process();
    return i;
}


下一步您需要做的就是定义拦截处理程序,您可以自定义裁缝以进行例外处理。使用此处理程序,您可以处理应用程序中所有异常。好处是,您不再需要使用TryCatch块标记所有代码。

public class MyCallHandler : ICallHandler, IDisposable
{
    public IMethodReturn Invoke(IMethodInvocation input, 
        GetNextHandlerDelegate getNext)
    {
        // call the method
        var methodReturn = getNext().Invoke(input, getNext);

        // check if an exception was raised.
        if (methodReturn.Exception != null)
        {
            // take the original exception and raise a new (correct) one...
            CreateSpecificFault(methodReturn.Exception);

            // set the original exception to null to avoid throwing yet another
            // exception
            methodReturn.Exception = null;
        }

        // complete the invoke...
        return methodReturn;
    }
}

可以通过配置文件或以编程方式将类注册到处理程序。代码相当简单。注册后,您可以使用统一实例化对象,例如:

var objectToUse = myUnityContainer.Resolve<MyObjectToUse>();

有关统一的更多信息:

http://msdn.microsoft.com/en-us/library/ff646991.aspx

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top