泛型的一点遗憾
在项目中,我定义了一个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;
}
}
然而,我总感到非常遗憾,既然泛型的where约束中可以使用new(),那么,为何不能提供带参的构造函数约束呢?例如这样的实现:
public static class ThrowHelperGeneric<TCustomException>
where TCustomException : ApplicationException, new(), new(string), new(string, Exception)
{
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);
}
}
不知在将来的C#版本中可否提供这样的泛型支持呢?莫非,实现这样的语法还存在相当的难度?
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;
}
}
然而,我总感到非常遗憾,既然泛型的where约束中可以使用new(),那么,为何不能提供带参的构造函数约束呢?例如这样的实现:
public static class ThrowHelperGeneric<TCustomException>
where TCustomException : ApplicationException, new(), new(string), new(string, Exception)
{
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);
}
}
不知在将来的C#版本中可否提供这样的泛型支持呢?莫非,实现这样的语法还存在相当的难度?
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
2005-09-01 Design & Pattern团队成员排行榜及文章推荐——八月篇
2005-09-01 在.Net中关于AOP的实现