前面介紹了倉儲的基本操作,下面准備開始擴展查詢,在擴展查詢之前,首先要增加兩個公共操作類,一個是經常要用到的驗證方法,另一個是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方法擴展的基礎。
我在下載的代碼中已經加入了后面兩篇需要用到的代碼文件,有興趣可以下載。
.Net應用程序框架交流QQ群: 386092459,歡迎有興趣的朋友加入討論。
謝謝大家的持續關注,我的博客地址:http://www.cnblogs.com/xiadao521/
下載地址:http://files.cnblogs.com/xiadao521/Util.2014.12.22.1.rar