分享一个参数检查的类

在函数中,通常需要对参数进行判断。如判断传入的参数是否为 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)
        {

        }
    }
}
原文地址:https://www.cnblogs.com/binblog/p/1863369.html