我正在编写一个服务,其中的方法不能抛出异常但应该返回一个通用的Message
- 对象,其中包含方法调用的实际结果和异常(如果有的话)。这个Message
类看起来像这样:
public class Message<T>
{
private List<Exception> exceptions = new List<Exception>();
public T Result { get; set; }
public void AddException(Exception x)
{
this.exceptions.Add(x);
}
public bool HasExceptions
{
get
{
return this.exceptions.Count > 0;
}
}
public IEnumerable<Exception> Exceptions
{
get
{
foreach (var exception in this.exceptions)
yield return exception;
}
}
}
通常,服务方法的实现如下所示:
public Message<int> MyServiceMethod()
{
var msg = new Message<int>();
try
{
// do something useful here
msg.Result = 42;
}
catch (Exception x)
{
msg.AddException(x);
}
return msg;
}
然后,调用者可以在必要时处理异常。
var msg = service.MyServiceMethod();
if (msg.HasExceptions)
{
// Handle exceptions here
}
现在我有一个带有参数的服务方法,该参数必须在一定范围内。因为如果参数超出范围我觉得用ArgumentOutOfRangeException
回答是很自然的,我实现了这样:
public Message<int> MyOtherServiceMethod(int arg)
{
var msg = new Message<int>();
if (arg < 1)
{
msg.AddException(new ArgumentOutOfRangeException("arg", "Argument must be greater than 0"));
return msg;
}
// ...
return msg;
}
基本上这是有效的。我唯一缺少的是异常的堆栈跟踪。这不是问题,因为在我的场景中我不需要这样做。但它让我想知道,还有其他任何副作用吗?#34;使用异常但不抛出时可能会造成麻烦?
答案 0 :(得分:0)
您应该使用一些以message
和exception
作为参数的构造:
try
{
// do something useful here
}
catch (Exception x)
{
throw YourPreferredException(some_message, x);
}
这会使x
可用作yourPreferredException.InnerException
属性。
此外,我不认为让方法返回Message
并在中运行try/catch
块是一个很好的设计选择(应该反过来说。)
答案 1 :(得分:0)
我会说这并不是C#中异常的预期用途。如果您需要自定义消息,那么您只需使用接收消息的Exception
构造函数和另一个类型为Exception
的实例,这将为您提供一个新的异常,其中包含您的自定义消息以及原始异常集作为实例InnerException
属性。你只需要在这里重新发明一些定制的消息&#39;类。如果您要做的只是返回一条消息(就像您不想抛出那样),那么您应该使用异常Message
属性并将其分配给某个字符串或直接返回该字符串。
以下是一些处理错误的惯用示例;
Message ret = new Message();
try
{}
catch (Exception e)
{
ret.ErrorPropertyOfTypeString = e.Message;
}
return ret;
Message ret = new Message();
try
{}
catch (Exception e)
{
throw new Exception("My custom message here", e);
}
return ret;
无论你做什么,上面两种模式中的一种都应该用来代替。