【发布时间】:2009-10-01 17:31:27
【问题描述】:
我正在设计一个验证服务,并在 Validate() 的两个不同方法签名之间进行辩论。两者都使用 lambda 表达式来获取对象的对象类型和属性以验证给定值。有定义为:
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);
}
哪个签名最有意义?为什么?
【问题讨论】: