ValidationService方法-“T2验证(表达式,T2)” vs “object Validate(表达式,对象)”

发布于 2024-08-06 07:16:00 字数 2389 浏览 3 评论 0原文

我正在设计一个验证服务,并且正在讨论 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);
}

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

I'm designing a validation service and I'm debating between two different method signatures for Validate(). Both use lambda Expressions to get the object type and property of the object to validate the given value. There are defined as:

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);
}

Here's a unit test for each so you can see the difference in usage:

[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"));
}

The first has two type parameters, one for the object type (T) and one for the property/value type (TProperty). This one is nice because the return type is TProperty, but its also a bit annoying because it has two type parameters.

The second has only one type parameter for the object type. The value is an object and also returns an object. This is nice because it only has one type parameter, but its also a bit annoying because I'll have to cast the return type from object to the property/value type.

I suppose another option would be adding a type parameter to the interface, IValidationService, which would eliminate the object type parameter (T) in both signatures:

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

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

Which signature makes the most sense and why?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

江南烟雨〆相思醉 2024-08-13 07:16:00

如果您坚持自己的界面理念,则可以使用 Validate而无需提供类型参数;编译器将通过检查方法参数的类型来推断类型参数。

否则,我个人更喜欢使用 Validate因为类型参数看起来比使用强制转换“更干净”。

If you roll with your interface idea, you can use Validate<TProperty> without needing to supply the type argument; the compiler will infer the type argument by inspecting the types of the method arguments.

Otherwise, my personal preference would be to use Validate<T, TProperty> since the type argument looks "cleaner" than using a cast.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文