• 分享一个参数检查的类


    在函数中,通常需要对参数进行判断。如判断传入的参数是否为 null,是否为Empty。

    做参数检查会降低代码的运行效率——因为多了判断,但是能有效提高代码健壮性。建议你至少应对公开的方法——包括public,internal的方法,进行参数检查。

     我们先看一段调用的代码,有个基本印象:

    Param.Check(value).NotNull().ThrowException("value 参数不能为 null").Execute();

    或者

    if (Param.Check(bytes).NotNull().Log("bytes 对象不能为 null").Execute())

    Param是一个类,静态方法:

    public static IChecker Check(object value)

    返回了一个 IChecker 接口对象

    IChecker接口中定义了很多检查的方法,如NotNull,NotEmpty等等


    IChecker 检查内容定义
        public interface IChecker
        {
            
    ///<summary>
            
    /// 要求参数长度为指定的长度。
            
    ///</summary>
            
    ///<param name="len">参数长度。</param>
            
    ///<returns>返回<see cref="IErrorProcessor"/>处理对象。</returns>
            IErrorProcessor LengthEqual(int len);

            
    /// <summary>
            
    /// 要求参数为 <c>true</c>
            
    /// </summary>
            
    /// <returns>返回<see cref="IErrorProcessor"/>处理对象。</returns>
            IErrorProcessor IsTrue();

            
    /// <summary>
            
    /// 要求参数不为 <c>null</c>
            
    /// </summary>
            
    /// <returns>返回<see cref="IErrorProcessor"/>处理对象。</returns>
            IErrorProcessor NotNull();

            
    /// <summary>
            
    /// 要求不能为空。
            
    /// </summary>
            
    /// <returns>返回<see cref="IErrorProcessor"/>处理对象。</returns>
            IErrorProcessor NotEmpty();

            
    /// <summary>
            
    /// 要求是指定类型的实例。
            
    /// </summary>
            
    /// <param name="type">指定的类型。</param>
            
    /// <returns>返回<see cref="IErrorProcessor"/>处理对象。</returns>
            IErrorProcessor IsInstanceOf(Type type);

            
    /// <summary>
            
    /// 要求在集合中。
            
    /// </summary>
            
    /// <param name="collection">集合。</param>
            
    /// <returns>返回<see cref="IErrorProcessor"/>处理对象。</returns>
            IErrorProcessor OneOf(IEnumerable collection);

            
    /// <summary>
            
    /// 要求不在集合中。
            
    /// </summary>
            
    /// <param name="collection">集合。</param>
            
    /// <returns>返回<see cref="IErrorProcessor"/>处理对象。</returns>
            IErrorProcessor NotOneOf(IEnumerable collection);

            
    /// <summary>
            
    /// 要求与另一值相等。
            
    /// </summary>
            
    /// <param name="value">另一参数。</param>
            
    /// <returns>返回<see cref="IErrorProcessor"/>处理对象。</returns>
            IErrorProcessor Equal(object value);
        }


    IChecker中的方法返回IErrorProcessor对象

    IErrorProcessor定义了如果检查出错时,该做什么处理——可以抛出异常、不做任何处理、记录日志等

    处理方式定义如下:

    ProcessMode 处理方式
        [Flags]
        
    public enum ProcessMode
        {
            
    ///<summary>
            
    /// 不做任何处理。
            
    ///</summary>
            None = 0,

            
    ///<summary>
            
    /// 在控制台中打印日志。
            
    ///</summary>
            Log = 1,

            
    ///<summary>
            
    /// 显示消息框。
            
    ///</summary>
            ShowMessage = 2,

            
    ///<summary>
            
    /// 抛出异常。
            
    ///</summary>
            ThrowException = 4,

            
    /// <summary>
            
    /// 显示Debug.Assert
            
    /// </summary>
            DebugAssert = 8
        }

    最后,调用Execute方法,执行检查。通过检查会返回 true,否则会根据处理方式进行相应的处理。 


    全部代码

    全部代码
    using System;
    using System.Collections;
    using System.Diagnostics;
    using System.Runtime.InteropServices;
    using System.Runtime.Serialization;

    namespace Ideal.ReferenceCodes
    {
        
    #region 接口
        
    ///<summary>
        
    /// 参数检查接口。
        
    ///</summary>
        public interface IChecker
        {
            
    ///<summary>
            
    /// 要求参数长度为指定的长度。
            
    ///</summary>
            
    ///<param name="len">参数长度。</param>
            
    ///<returns>返回<see cref="IErrorProcessor"/>处理对象。</returns>
            IErrorProcessor LengthEqual(int len);

            
    /// <summary>
            
    /// 要求参数为 <c>true</c>
            
    /// </summary>
            
    /// <returns>返回<see cref="IErrorProcessor"/>处理对象。</returns>
            IErrorProcessor IsTrue();

            
    /// <summary>
            
    /// 要求参数不为 <c>null</c>
            
    /// </summary>
            
    /// <returns>返回<see cref="IErrorProcessor"/>处理对象。</returns>
            IErrorProcessor NotNull();

            
    /// <summary>
            
    /// 要求不能为空。
            
    /// </summary>
            
    /// <returns>返回<see cref="IErrorProcessor"/>处理对象。</returns>
            IErrorProcessor NotEmpty();

            
    /// <summary>
            
    /// 要求是指定类型的实例。
            
    /// </summary>
            
    /// <param name="type">指定的类型。</param>
            
    /// <returns>返回<see cref="IErrorProcessor"/>处理对象。</returns>
            IErrorProcessor IsInstanceOf(Type type);

            
    /// <summary>
            
    /// 要求在集合中。
            
    /// </summary>
            
    /// <param name="collection">集合。</param>
            
    /// <returns>返回<see cref="IErrorProcessor"/>处理对象。</returns>
            IErrorProcessor OneOf(IEnumerable collection);

            
    /// <summary>
            
    /// 要求不在集合中。
            
    /// </summary>
            
    /// <param name="collection">集合。</param>
            
    /// <returns>返回<see cref="IErrorProcessor"/>处理对象。</returns>
            IErrorProcessor NotOneOf(IEnumerable collection);

            
    /// <summary>
            
    /// 要求与另一值相等。
            
    /// </summary>
            
    /// <param name="value">另一参数。</param>
            
    /// <returns>返回<see cref="IErrorProcessor"/>处理对象。</returns>
            IErrorProcessor Equal(object value);
        }

        
    /// <summary>
        
    /// 参数错误处理接口。
        
    /// </summary>
        public interface IErrorProcessor : IExecute
        {
            
    /// <summary>
            
    /// 抛出参数错误的异常。
            
    /// </summary>
            
    /// <returns>返回<see cref="IExecute"/>的实例。</returns>
            IExecute ThrowException();

            
    /// <summary>
            
    /// 抛出参数错误的异常。
            
    /// </summary>
            
    /// <param name="msg">显示的错误消息。</param>
            
    /// <returns>返回<see cref="IExecute"/>的实例。</returns>
            IExecute ThrowException(string msg);

            
    /// <summary>
            
    /// 显示在控制台。
            
    /// </summary>
            
    /// <returns>返回<see cref="IExecute"/>的实例。</returns>
            IExecute Log();

            
    /// <summary>
            
    /// 显示在控制台。
            
    /// </summary>
            
    /// <param name="msg">显示的错误消息。</param>
            
    /// <returns>返回<see cref="IExecute"/>的实例。</returns>
            IExecute Log(string msg);

            
    /// <summary>
            
    /// 不做任何处理。
            
    /// </summary>
            
    /// <returns>返回<see cref="IExecute"/>的实例。</returns>
            IExecute DoNothing();

            
    /// <summary>
            
    /// 显示弹出消息框。
            
    /// </summary>
            
    /// <returns>返回<see cref="IExecute"/>的实例。</returns>
            IExecute ShowMessage();

            
    /// <summary>
            
    /// 显示弹出消息框。
            
    /// </summary>
            
    /// <param name="msg">显示的消息内容。</param>
            
    /// <returns>返回<see cref="IExecute"/>的实例。</returns>
            IExecute ShowMessage(string msg);

            
    /// <summary>
            
    /// 弹出 Debug.Assert 窗口。
            
    /// </summary>
            
    /// <returns>返回<see cref="IExecute"/>的实例。</returns>
            IExecute Assert();

            
    /// <summary>
            
    /// 弹出 Debug.Assert 窗口。
            
    /// </summary>
            
    /// <param name="msg">显示的消息内容。</param>
            
    /// <returns>返回<see cref="IExecute"/>的实例。</returns>
            IExecute Assert(string msg);
        }

        
    /// <summary>
        
    /// 执行参数检查接口。
        
    /// </summary>
        public interface IExecute
        {
            
    /// <summary>
            
    /// 执行参数检查。
            
    /// </summary>
            bool Execute();
        }

        
    #endregion

        
    ///<summary>
        
    /// 参数检查处理类。
        
    ///</summary>
        public sealed class Param : IChecker, IErrorProcessor
        {
            
    delegate bool CheckDelegate();

            
    private static ProcessMode _default = ProcessMode.DebugAssert;
            
    /// <summary>
            
    /// 获取或设置参数默认处理模式
            
    /// </summary>
            public static ProcessMode Default { get { return _default; } set { _default = value; } }
            
    private readonly object o;
            
    private CheckDelegate _check;
            
    private ProcessMode mode = Default;
            
    private string _msg;

            
    private Param(object o)
            {
                
    this.o = o;
            }

            
    ///<summary>
            
    /// 检查参数。
            
    ///</summary>
            
    ///<param name="value">检查的对象。</param>
            
    ///<returns>返回<see cref="IChecker"/>的实例。</returns>
            public static IChecker Check(object value)
            {
                
    return new Param(value);
            }


            
    #region Execute

            
    bool IExecute.Execute()
            {
                
    if (_check == nullreturn true;
                
    if (_check()) return true;
                
    switch (mode)
                {
                    
    case ProcessMode.None:
                        
    break;
                    
    case ProcessMode.Log:
                        Console.WriteLine(
    "参数检查错误:{0}\r\n{1}", _msg, new StackTrace());
                        
    break;
                    
    case ProcessMode.ShowMessage:
                        
    int result = NativeMethods.MessageBox(IntPtr.Zero, "参数检查错误:" + _msg + "\r\n" + new StackTrace(), "参数警告"0);
                        
    return result == -1;
                    
    case ProcessMode.ThrowException:
                        
    throw new ParamException(_msg);
                    
    case ProcessMode.DebugAssert:
                        Debug.Assert(
    false"参数检查错误:" + _msg, new StackTrace().ToString());
                        
    break;
                    
    default:
                        
    throw new ParamException("错误处理模式未知。");
                }
                
    return false;
            }
            
    #endregion

            
    #region NativeMethods

            
    private class NativeMethods
            {
                
    private NativeMethods()
                {

                }
                [DllImport(
    "user32.dll", CharSet = CharSet.Unicode)]
                
    public static extern int MessageBox(IntPtr hWnd, String text, String caption, int options);
            }
            
    #endregion

            
    #region Implementation of IChecker

            IErrorProcessor IChecker.LengthEqual(
    int len)
            {
                _msg 
    = "要求参数长度为 " + len;
                _check 
    = delegate
                             {
                                 
    if (o is string)
                                 {
                                     
    return ((string)o).Length == len;
                                 }
                                 
    if (o is Array)
                                 {
                                     
    return ((Array)o).Length == len;
                                 }
                                 
    return false;
                             };
                
    return this;
            }

            IErrorProcessor IChecker.IsTrue()
            {
                _msg 
    = "要求参数值为 true";
                _check 
    = delegate { return (o is bool&& ((bool)o); };
                
    return this;
            }

            IErrorProcessor IChecker.NotNull()
            {
                _msg 
    = "要求参数值不为 null";
                _check 
    = delegate { return o != null; };
                
    return this;
            }

            IErrorProcessor IChecker.NotEmpty()
            {
                _msg 
    = "要求参数值不为空";
                _check 
    = delegate
                {
                    
    if ((o is string&& (((string)o).Length == 0))
                    {
                        
    return false;
                    }
                    
    if ((o is Array) && (((Array)o).Length == 0))
                    {
                        
    return false;
                    }
                    
    return !(o is DBNull);
                };
                
    return this;
            }

            IErrorProcessor IChecker.IsInstanceOf(Type type)
            {
                
    if (type == null)
                {
                    
    throw new ArgumentNullException("type""检查参数时出错,调用方法 IsInstanceOf(Type) 的 type参数不能为 null");
                }
                _msg 
    = "要求参数是 " + type.FullName + " 的实例";

                _check 
    = delegate { return type.IsInstanceOfType(o); };
                
    return this;
            }

            IErrorProcessor IChecker.OneOf(IEnumerable collection)
            {
                _msg 
    = "要求参数值包含在集合中";
                _check 
    = delegate
                             {
                                 
    foreach (var enumItem in collection)
                                 {
                                     
    if (enumItem == o) return true;
                                 }
                                 
    return false;
                             };
                
    return this;
            }

            IErrorProcessor IChecker.NotOneOf(IEnumerable collection)
            {
                _msg 
    = "要求参数值不在集合中";
                _check 
    = delegate
                             {
                                 
    foreach (var enumItem in collection)
                                 {
                                     
    if (enumItem == o) return false;
                                 }
                                 
    return true;
                             };
                
    return this;
            }

            IErrorProcessor IChecker.Equal(
    object value)
            {
                _msg 
    = "要求参数值与" + value + "相等";
                _check 
    = delegate { return value.Equals(o); };
                
    return this;
            }

            
    #endregion

            
    #region Implementation of IErrorProcessor

            IExecute IErrorProcessor.ThrowException()
            {
                mode 
    = ProcessMode.ThrowException;
                
    return this;
            }

            IExecute IErrorProcessor.ThrowException(
    string msg)
            {
                mode 
    = ProcessMode.ThrowException;
                _msg 
    = msg;
                
    return this;
            }

            IExecute IErrorProcessor.Log()
            {
                mode 
    = ProcessMode.Log;
                
    return this;
            }

            IExecute IErrorProcessor.Log(
    string msg)
            {
                mode 
    = ProcessMode.Log;
                _msg 
    = msg;
                
    return this;
            }

            IExecute IErrorProcessor.DoNothing()
            {
                mode 
    = ProcessMode.None;
                
    return this;
            }

            IExecute IErrorProcessor.ShowMessage()
            {
                mode 
    = ProcessMode.ShowMessage;
                
    return this;
            }

            IExecute IErrorProcessor.ShowMessage(
    string msg)
            {
                mode 
    = ProcessMode.ShowMessage;
                _msg 
    = msg;
                
    return this;
            }

            IExecute IErrorProcessor.Assert()
            {
                mode 
    = ProcessMode.DebugAssert;
                
    return this;
            }

            IExecute IErrorProcessor.Assert(
    string msg)
            {
                mode 
    = ProcessMode.DebugAssert;
                _msg 
    = msg;
                
    return this;
            }

            
    #endregion
        }
        
    ///<summary>
        
    /// 处理模式。
        
    ///</summary>
        [Flags]
        
    public enum ProcessMode
        {
            
    ///<summary>
            
    /// 不做任何处理。
            
    ///</summary>
            None = 0,

            
    ///<summary>
            
    /// 在控制台中打印日志。
            
    ///</summary>
            Log = 1,

            
    ///<summary>
            
    /// 显示消息框。
            
    ///</summary>
            ShowMessage = 2,

            
    ///<summary>
            
    /// 抛出异常。
            
    ///</summary>
            ThrowException = 4,

            
    /// <summary>
            
    /// 显示Debug.Assert
            
    /// </summary>
            DebugAssert = 8
        }

        
    /// <summary>
        
    /// 参数检查错误。
        
    /// </summary>
        [Serializable]
        
    public class ParamException : Exception
        {
            
    /// <summary>
            
    /// 初始化<see cref="ParamException"/>的实例。
            
    /// </summary>
            
    /// <param name="msg">错误消息。</param>
            public ParamException(string msg)
                : 
    this(msg, null)
            {

            }


            
    /// <summary>
            
    /// 初始化<see cref="ParamException"/>的实例。
            
    /// </summary>
            public ParamException()
                : 
    this(string.Empty, null)
            {

            }

            
    /// <summary>
            
    /// 初始化<see cref="ParamException"/>的实例。
            
    /// </summary>
            
    /// <param name="msg">错误消息。</param>
            
    /// <param name="innerException">内部异常。</param>
            public ParamException(string msg, Exception innerException)
                : 
    base(string.Format(null"未通过参数检查:{0}", msg), innerException)
            {

            }

            
    /// <summary>
            
    /// 用序列化数据初始化 <see cref="ParamException"/> 类的新实例。
            
    /// </summary>
            
    /// <param name="info">它存有有关所引发异常的序列化的对象数据</param>
            
    /// <param name="context">它包含有关源或目标的上下文信息</param>
            protected ParamException(SerializationInfo info, StreamingContext context)
                : 
    base(info, context)
            {

            }
        }
    }
  • 相关阅读:
    [uoj173]鏖战表达式
    [cf1168E]Xor Permutations
    [cf578F]Mirror Box
    [cf1261F]Xor-Set
    [loj2506]tree
    [atARC068F]Solitaire
    [atARC066F]Contest with Drinks Hard
    [cf1270I]Xor on Figures
    [cf516D]Drazil and Morning Exercise
    无题
  • 原文地址:https://www.cnblogs.com/binblog/p/1863369.html
Copyright © 2020-2023  润新知