zoukankan      html  css  js  c++  java
  • 泛型的一点遗憾

    在项目中,我定义了一个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#版本中可否提供这样的泛型支持呢?莫非,实现这样的语法还存在相当的难度?
  • 相关阅读:
    C# 多线程并发锁模式-总结
    C# 7 out variables, tuples & other new features
    AngleSharp 的Dom 选择器
    Html Agility Pack
    javascript判断是否按回车键
    VSTS 免费代码git/tfs托管体验-使用代码云托管
    NPOI 中的公式列的值的获取
    topshelf 开发windows 服务资料
    vue之指令
    hash和md5
  • 原文地址:https://www.cnblogs.com/wayfarer/p/1281350.html
Copyright © 2011-2022 走看看