Я разрабатываю службу проверки и спорю между двумя разными сигнатурами методов для Validate (). Оба используют лямбда-выражения для получения типа объекта и свойства объекта для проверки заданного значения. Там определены как:
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);
}
Какая подпись имеет смысл и почему?