由于我做了很多参数null检查,我想稍微简化一下。我创建了以下方法:
public static void ThrowExceptionIf<TException>(bool condition, string message = null, params KeyValuePair<string, string>[] data) where TException : Exception, new()
{
if (condition)
{
return;
}
var exception = new TException();
data.AsParallel().ForAll(d => exception.Data.Add(d.Key, d.Value));
throw exception;
}
使用方法如下:
public ValidatableBase(IUser user, IEventAggregator eventService)
: this()
{
ExceptionFactory
.ThrowExceptionIf<ArgumentNullException>(user == null || eventService == null);
this.user = user;
this.EventService = eventService;
}
但问题是我无法为异常分配消息。 Message属性是只读的,并且泛型不会看到受约束的Type接受参数。
我见过一些人实例CustomException
并通过其构造函数传递消息,并将InnerException
指定为给定的异常(在本例中为TException
)但我想要在去那条路线之前询问是否有其他选择。将工厂抛出的所有异常包装在自定义异常中似乎是糟糕的设计。
最终工厂使用了每个人的答案并且效果很好。
public static void ThrowExceptionIf<TException>(bool condition, string message = null, IUser user = null, params KeyValuePair<string, string>[] data) where TException : Exception, new()
{
ThrowExceptionIf<TException>(
condition,
() => (TException) Activator.CreateInstance(typeof (TException), message),
user,
data);
}
public static void ThrowExceptionIf<TException>(Func<bool> predicate, string message = null, IUser user = null, params KeyValuePair<string, string>[] data) where TException : Exception, new()
{
ThrowExceptionIf<TException>(predicate(), message, user, data);
}
public static void ThrowExceptionIf<TException>(bool condition, Func<TException> exception, IUser user = null, params KeyValuePair<string, string>[] data) where TException : Exception, new()
{
if (condition)
{
return;
}
TException exceptionToThrow = exception();
AddExceptionData(exceptionToThrow, user, data);
throw exceptionToThrow;
}
public static void AddExceptionData(Exception exception, IUser user = null, params KeyValuePair<string, string>[] data)
{
foreach (var exceptionData in data)
{
exception.Data.Add(exceptionData.Key, exceptionData.Value);
}
if (user != null)
{
exception.Data.Add("User", user.RacfId);
}
}
我现在可以通过以下方式使用ThrowExceptionIf
方法
ThrowExceptionIf<ArgumentNullException>(
user == null,
"Users can not be null.");
ThrowExceptionIf<ArgumentNullException>(
user == null,
() => new ArgumentNullException("user", "Users can not be null"));
ThrowExceptionIf<ArgumentException>(
() => user.FirstName.Equals(user.LastName),
"last name must not equal the first name");
感谢您的帮助!
答案 0 :(得分:3)
您还可以将创建lambda方法而不是消息传递给throw方法:
public static void ThrowExceptionIf<TException>(bool condition, Func<TException> init, params KeyValuePair<string, string>[] data) where TException : Exception
{
if (condition)
{
return;
}
var exception = init();
data.AsParallel().ForAll(d => exception.Data.Add(d.Key, d.Value));
throw exception;
}
然后像ThrowExceptionIf(true, ()=>new ArgumentNullException("foo"));
一样打电话。
答案 1 :(得分:2)
你可以:
throw (TException)Activator.CreateInstance(typeof(TException), message, inner);