技术开发 频道

C#中泛型的一点遗憾

【IT168专稿】在项目中,我定义了一个ThrowHelper辅助类,用于抛出项目中的自定义异常。例如定义了这样的一个异常:

public class EmployeeException:ApplicationException
{
    
public EmployeeException()
        : base()
    { }

    
public EmployeeException(string message)
        : base(message)
    { }

    
public EmployeeException(string message, Exception innerException)
        : base(message, innerException)
    { }
}

   我们可以在ThrowHelper中定义抛出该异常的方法,以便于调用者调用: 

public static class ThrowHelper
{
    
public static EmployeeException ThrowEmployeeException(string message)
    {
        LogService.Error(message);
        throw
new EmployeeException(message);
    }

    
public static EmployeeException ThrowEmployeeException(string message, Exception innerException)
    {
        LogService.Error(message, innerException);
        throw
new EmployeeException(message, innerException);
    }
}

   一个问题是当我们定义了多个自定义异常时,我们需要不断地向ThrowHelper添加新的方法。这就像是在记流水账。开发人员不可能喜欢这样的重复劳动。

   那么,我们是否可以利用泛型来解决这一问题呢?例如定义该辅助类的泛型版本:
 

public static class ThrowHelperGeneric<TCustomException>
    where TCustomException : ApplicationException,
new()
{
    
public static TCustomException ThrowCustomException(string message)
    {
        LogService.Error(message);
        throw
new TCustomException(message);
    }

    
public static TCustomException ThrowCustomException(string message, Exception innerException)
    {
        LogService.Error(message, innerException);
        throw
new TCustomException(message, innerException);
    }
}

   可惜,泛型类型并不支持带参的构造函数调用。要解决这一问题,只有使用反射技术。实现如下:

public static class ThrowHelperGeneric<TCustomException>
    where TCustomException : ApplicationException,
new()
{
    
public static TCustomException ThrowCustomException(string message)
    {
        LogService.Error(message);
        TCustomException exception
= (TCustomException)typeof(TCustomException).GetConstructor(new Type[] { typeof(string) }).
            Invoke(
new object[] { message });

        throw exception;
    }

    
public static TCustomException ThrowCustomException(string message, Exception innerException)
    {
        LogService.Error(message,innerException);
        TCustomException exception
= (TCustomException)typeof(TCustomException).GetConstructor(new Type[] { typeof(string), typeof(Exception) }).
            Invoke(
new object[] { message, innerException });

        throw exception;
    }
}


 

0
相关文章