【问题标题】:ValidationService method - "T2 Validate<T1, T2>(Expression, T2)" vs "object Validate<T1>(Expression, object)"ValidationService 方法 - “T2 Validate<T1, T2>(Expression, T2)” vs “object Validate<T1>(Expression, object)”
【发布时间】: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);
}

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

【问题讨论】:

    标签: c# .net generics lambda


    【解决方案1】:

    如果你喜欢你的界面想法,你可以使用Validate&lt;TProperty&gt;而不需要提供类型参数;编译器将通过检查方法参数的类型来推断类型参数。

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

    【讨论】:

    • 我没有意识到 TProperty 可以从通用接口中推断出来。我喜欢它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-20
    • 2018-10-25
    相关资源
    最近更新 更多