I’m making an object validation framework in my spare time to learn a few things and maybe use it for some school projects.
I have my generic Rule class, which looks something like this :
class Rule<T>
{
string propertyName;
Func<T, bool> ruleLambda;
bool IsBroken(T value)
{
return ruleLambda(value);
}
}
An object that would be validated would look a bit like this :
class Example
{
List<Rule<?>> MyRules; // can take all types of rules
List<Rule<T>> Validate<T>(string propertyName, T value)
{
List<Rule<T>> brokenRules = new List<Rule<T>>();
foreach (Rule rule in MyRules.Where(r => r.propertyName == propertyName))
{
if (rule.IsBroken(value))
brokenRules.Add(rule);
}
return brokenRules;
}
}
Where the T value argument would be the value of one of the Example class’s properties, which can be of any type.
The Validate<T> method is called whenever a property is set.
The problem lies with the class’s list of rules. Specifically the List<Rule<?>> line above. I want to store all the rules for a given class in the same list.
Alas, C# doesn’t have a wildcard for generic types like in Java.
How should I do this?
A non-generic interface or base class utilizing objects instead of T could work, but how would I call the generic Rule’s IsBroken method and not the non-generic one?
I’ve tried a few things and I’ve found something that works pretty well for my needs. I have
Rule<T>inherit from a base abstract rule class, with a genericIsBrokenmethod:As you can see, I try to convert the base class to its generic counterpart using the generic type parameter in the
IsBrokenmethod.Also, when creating a
Rule<T>instance, I send aFunc<object, bool>to its base class protected constructor:With the conversion method looking like this:
However, if it can’t cast o to type T, it crashes. So I wrote this… thing:
It’s pretty ugly, but it works. Hope this can help anybody else.