验证扩展

前面介绍了仓储的基本操作,下面准备开始扩展查询,在扩展查询之前,首先要增加两个公共操作类,一个是经常要用到的验证方法,另一个是Lambda表达式的操作类。

很多时候,我们会判断一个对象是否为null,由于null是一个不能接受的值,它会导致“未将对象引用设置到对象的实例”的严重错误,所以当检测到null值时一般直接抛出ArgumentNullException异常。

public void Test( string name ) {
    if( name == null )
         throw new ArgumentNullException( "name" );
    //其它操作
}    

由于判断null是一个频繁操作,可以用一个扩展方法来封装它,像下面这样调用。

public void Test( string name ) {
    name.CheckNull( "name" );
    //其它操作
}

我直接将CheckNull扩展到object对象上,因为绝大部分对象都需要这个操作。注意,扩展object要非常谨慎,会导致大面积污染,因为所有对象都会看见这个扩展方法,如果这个操作对某些对象有副作用,就会造成更多混乱。

另一个常用的方法也是判断是否为空,比如字符串的””,或者Guid的Guid.Empty。

对于string,我们一般通过string.IsNullOrWhiteSpace来进行判断。

public void Test( string name ) {
    if ( string.IsNullOrWhiteSpace( name ) )
        return;
    //其它操作
}

使用扩展方法封装后,简化为下面的代码。

public void Test( string name ) {
    if ( name.IsEmpty() )
        return;
    //其它操作
}

IsEmpty扩展方法,我定义在string、Guid、Guid?等具体类型上,不能扩展到object,因为每种类型的实现不同,当然可以进行各种判断,但执行效率可能非常低下,毕竟这是一个常用方法。

在Util项目中添加Extensions.Validate文件,它是Extensions的部分类,代码如下。

using System;

namespace Util {
    /// <summary>
    /// 验证扩展
    /// </summary>
    public static partial class Extensions {
        /// <summary>
        /// 检测空值,为null则抛出ArgumentNullException异常
        /// </summary>
        /// <param name="obj">对象</param>
        /// <param name="parameterName">参数名</param>
        public static void CheckNull( this object obj, string parameterName ) {
            if ( obj == null )
                throw new ArgumentNullException( parameterName );
        }

        /// <summary>
        /// 是否为空
        /// </summary>
        /// <param name="value">值</param>
        public static bool IsEmpty( this string value ) {
            return string.IsNullOrWhiteSpace( value );
        }

        /// <summary>
        /// 是否为空
        /// </summary>
        /// <param name="value">值</param>
        public static bool IsEmpty( this Guid? value ) {
            if ( value == null )
                return true;
            return IsEmpty( value.Value );
        }

        /// <summary>
        /// 是否为空
        /// </summary>
        /// <param name="value">值</param>
        public static bool IsEmpty( this Guid value ) {
            if ( value == Guid.Empty )
                return true;
            return false;
        }
    }
}

单元测试代码如下。

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Util.Tests.Extensions {
    /// <summary>
    /// 验证扩展测试
    /// </summary>
    [TestClass]
    public class ValidateExtensionTest {
        /// <summary>
        /// 检查空值,不为空则正常执行
        /// </summary>
        [TestMethod]
        public void TestCheckNull() {
            var test = new object();
            test.CheckNull( "test" );
        }

        /// <summary>
        /// 检查空值,值为null则抛出异常
        /// </summary>
        [TestMethod]
        [ExpectedException( typeof( ArgumentNullException ) )]
        public void TestCheckNull_Null_Throw() {
            try {
                object test = null;
                test.CheckNull( "test" );
            }
            catch ( ArgumentNullException ex ) {
                Assert.IsTrue( ex.Message.Contains( "test" ), ex.Message );
                throw;
            }
        }

        /// <summary>
        /// 测试是否空值
        /// </summary>
        [TestMethod]
        public void TestIsEmpty_String() {
            string value = null;
            Assert.IsTrue( value.IsEmpty() );
            Assert.IsTrue( "".IsEmpty() );
            Assert.IsTrue( " ".IsEmpty() );
            Assert.IsFalse( "a".IsEmpty() );
        }

        /// <summary>
        /// 测试是否空值
        /// </summary>
        [TestMethod]
        public void TestIsEmpty_Guid() {
            Guid value = Guid.Empty;
            Assert.IsTrue( value.IsEmpty() );
            value = Guid.NewGuid();
            Assert.IsFalse( value.IsEmpty() );
        }

        /// <summary>
        /// 测试是否空值
        /// </summary>
        [TestMethod]
        public void TestIsEmpty_Guid_Nullable() {
            Guid? value = null;
            Assert.IsTrue( value.IsEmpty() );
            value = Guid.Empty;
            Assert.IsTrue( value.IsEmpty() );
            value = Guid.NewGuid();
            Assert.IsFalse( value.IsEmpty() );
        }
    }
}

本文简单介绍了两个验证方法的扩展,下一篇将介绍对Lambda表达式的操作进行封装,它是对IQueryable核心Where方法扩展的基础。

我在下载的代码中已经加入了后面两篇需要用到的代码文件,有兴趣可以下载。

下载地址:http://files.cnblogs.com/xiadao521/Util.2014.12.22.1.rar

应用程序框架实战