我正在設計一個驗證服務,並且我在兩個不同的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);
}
這簽名是很有道理的,爲什麼?
我沒有意識到TProperty可以從通用接口推斷出來。我喜歡。 – jrummell 2009-10-01 17:54:56