c# - 分配通用异常 <TException> 一条消息

标签 c# exception generics factory-pattern

因为我做了很多参数空值检查,所以我想稍微简化一下。我创建了以下方法:

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");

感谢您的帮助!

最佳答案

您还可以将创建 lambda 方法而不是消息传递给 throwing 方法:

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"));

关于c# - 分配通用异常 <TException> 一条消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26718904/

相关文章:

java线程异常

mysql - Node MySQL 错误 - 错误 : Cannot enqueue Quit after invoking quit

java - 具有泛型和反射的可扩展工厂类

c# - 如何传递一个对象类型来调用泛型方法

c# - 是否可以取消选择 RadioButton 组中的所有值?

c# - MaasOne yahoo-finance-managed 为 AlphabeticIDIndexResult 返回零结果

c# - 悖论 DB : cyrillic words in a query, C#

c# - 奇怪的 .Net 序列化问题

phpunit 测试 expectedException 不工作

swift - 使用 Swift `is` 检查泛型类型