Assume i have a class like this below
class Student
{
public int ID { get; set; }
public string Name { get; set; }
}
Just with 10 more properties. I want to loop through these properties. I can do it through reflection, which will have a performance cost. Is serializing it using Newtonsoft JSON and looping through it better?
Edit: The reason i want to do this is there are many classes like this. Each of these classes also has a Ienumerable object as below
public bool Validation
{
public string PropName { get; set; }
public bool IsRequired { get; set; }
public int? MaxLength { get; set; }
public int? MinLength { get; set; }
public void Validate(object propValue)
{... }
}
I want to loop through each property in student class, take values and supply it to validate method. But i don't want to use reflection. I am not sure if it is even possible. Let me know if u have any thoughts.
If you are disturbed by performance hit of the reflection you can "cache" it using generic static classes and private static fields in them (which are not shared) and some compilation magic using expression trees. For example (modified your code to make it compile):
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; }
}
Which can be used like this:
var x = new Student();
var validations = new[]
{
new Validation
{
PropName = "Name",
IsRequired = true,
MinLength = 1,
MaxLength = 10
}
};
Validator<Student>.Validate(x, validations);
This code can be improved(for example if IEnumerable<Validation>
is collection on the class itself you can move code getting it to another static property and remove corresponding parameter of Validator.Validate
)