Если вас беспокоит снижение производительности отражения, вы можете "кэшировать" его, используя общие c stati c классы и частные поля stati c в них (которые не являются общими) и некоторые маги компиляции c используя деревья выражений . Например (изменил ваш код, чтобы он скомпилировался):
public static class Validator<T>
{
private static readonly Dictionary<string, Func<T, object>> propGetters;
static Validator()
{
propGetters =
typeof(T)
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Where(p => p.GetGetMethod() != null)
.ToDictionary(p => p.Name, p =>
{
var par = Expression.Parameter(typeof(T));
var access = Expression.Property(par, p);
var lambda = Expression.Lambda<Func<T, object>>(Expression.Convert(access, typeof(object)), par);
return lambda.Compile();
});
}
public static bool Validate(T c, IEnumerable<Validation> v)
{
return v.All(v => v.Validate(propGetters[v.PropName](c)));
}
}
class Student
{
public int ID { get; set; }
public string Name { get; set; }
}
public class Validation
{
public string PropName { get; set; }
public bool IsRequired { get; set; }
public int? MaxLength { get; set; }
public int? MinLength { get; set; }
public bool Validate(object propValue)
{ return false; }
}
Что можно использовать следующим образом:
var x = new Student();
var validations = new[]
{
new Validation
{
PropName = "Name",
IsRequired = true,
MinLength = 1,
MaxLength = 10
}
};
Validator<Student>.Validate(x, validations);
Этот код можно улучшить (например, если IEnumerable<Validation>
является коллекцию в самом классе, вы можете переместить код, получив его в другое свойство stati c, и удалить соответствующий параметр Validator.Validate
)