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#版本中可否提供这样的泛型支持呢?莫非,实现这样的语法还存在相当的难度?
  • 相关阅读:
    小波变换的引入,通俗易懂
    Leetcode 437. Path Sum III
    Leetcode 113. Path Sum II
    Leetcode 112 Path Sum
    Leetcode 520 Detect Capital
    Leetcode 443 String Compression
    Leetcode 38 Count and Say
    python中的生成器(generator)总结
    python的random模块及加权随机算法的python实现
    leetcode 24. Swap Nodes in Pairs(链表)
  • 原文地址:https://www.cnblogs.com/wayfarer/p/1281350.html
Copyright © 2011-2022 走看看