2009-10-01 106 views
1

我正在設計一個驗證服務,並且我在兩個不同的Validate()方法簽名之間進行辯論。兩者都使用lambda表達式來獲取對象的對象類型和屬性以驗證給定的值。有被定義爲:驗證服務方法 - 「T2驗證<T1, T2>(表達式,T2)」vs「對象驗證<T1>(Expression,object)」

public interface IValidationService 
{ 
    /// <summary> 
    /// Validates the value of the property returned by the property expression. 
    /// </summary> 
    /// <typeparam name="T">The type of the object to validate.</typeparam> 
    /// <typeparam name="TProperty">The type of the property.</typeparam> 
    /// <param name="propertyExpression">The property expression.</param> 
    /// <param name="value">The value.</param> 
    /// <returns></returns> 
    TProperty Validate<T, TProperty>(Expression<Func<T, TProperty>> propertyExpression, TProperty value); 

    /// <summary> 
    /// Validates the value of the property returned by the property expression. 
    /// </summary> 
    /// <typeparam name="T">The type of the object to validate.</typeparam> 
    /// <param name="propertyExpression">The property expression.</param> 
    /// <param name="value">The value.</param> 
    /// <returns></returns> 
    object Validate<T>(Expression<Func<T, object>> propertyExpression, object value); 
} 

這裏是爲每個單元測試,以便可以看到在使用的區別:

[Test] 
public void ValidateCustomerId_Method1() 
{ 
    string id = "123456789123"; 
    string validatedId = _validationService.Validate<Customer, string>(x => x.Id, id); 
    Assert.That(validatedId, Is.EqualTo("123456789")); 
} 

[Test] 
public void ValidateCustomerId_Method2() 
{ 
    string id = "123456789123"; 
    string validatedId = (string) _validationService.Validate<Customer>(x => x.Id, id); 
    Assert.That(validatedId, Is.EqualTo("123456789")); 
} 

第一有兩個類型參數,一個對象類型(T)和一個用於屬性/值類型(TProperty)。這一個很好,因爲返回類型是TProperty,但它也有點煩人,因爲它有兩個類型參數。

第二隻有一個對象類型的類型參數。該值是一個對象並返回一個對象。這很好,因爲它只有一個類型參數,但它也有點煩人,因爲我必須將對象的返回類型轉換爲屬性/值類型。

我想另一種辦法是增加一個類型參數的接口,IValidationService,這將消除對象類型參數(T)在這兩個標記:

public interface IValidationService<T> 
{ 
    TProperty Validate<TProperty>(Expression<Func<T, TProperty>> propertyExpression, TProperty value); 

    object Validate(Expression<Func<T, object>> propertyExpression, object value); 
} 

這簽名是很有道理的,爲什麼?

回答

3

如果您使用界面構思滾動,則可以使用Validate<TProperty>,而無需提供類型參數;編譯器會通過檢查方法參數的類型來推斷類型參數。

否則,我個人的偏好是使用Validate<T, TProperty>因爲論據看起來「乾淨」比使用強制類型。

+0

我沒有意識到TProperty可以從通用接口推斷出來。我喜歡。 – jrummell 2009-10-01 17:54:56