ValidationService方法 - “T2验证<t1,t2 =”“>(表达式,T2)”vs“对象验证<t1>(表达式,对象)”</t1> </t1,>

时间:2009-10-01 17:31:28

标签: c# .net generics lambda

我正在设计验证服务,我正在为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);
}

哪种签名最有意义?为什么?

1 个答案:

答案 0 :(得分:3)

如果您使用界面构思滚动,则可以使用Validate<TProperty>而无需提供类型参数;编译器将通过检查方法参数的类型来推断类型参数。

否则,我个人的偏好是使用Validate<T, TProperty>,因为类型参数看起来比使用强制转换更“干净”。