Примечание: Следующее решение - шутка между мной и Эриком Липпертом.Это работает, но, вероятно, не рекомендуется.
Идея состоит в том, чтобы определить параметр универсального типа, который ссылается на «текущий» тип (например, this
относится к «текущему» объекту).
HierarchyBase:
class HierarchyBase<T>
where T : HierarchyBase<T>
{
protected readonly List<Func<T, bool>> validators;
public HierarchyBase()
{
validators = new List<Func<T, bool>>();
validators.Add(x => x.A % 2 == 0);
}
public int A { get; set; }
public bool Validate()
{
return validators.All(validator => validator((T)this));
}
}
HierarchyBaseInheritorA:
class HierarchyBaseInheritorA<T> : HierarchyBase<T>
where T : HierarchyBaseInheritorA<T>
{
public HierarchyBaseInheritorA()
{
validators.Add(x => x.A > 10);
validators.Add(x => x.B != 0);
}
public int B { get; set; }
}
HierarchyBaseInheritorB:
class HierarchyBaseInheritorB : HierarchyBaseInheritorA<HierarchyBaseInheritorB>
{
public HierarchyBaseInheritorB()
{
validators.Add(x => x.A < 20);
validators.Add(x => x.B > 0);
validators.Add(x => x.C == 0);
}
public int C { get; set; }
}
Использование:
var result = new HierarchyBaseInheritorB();
result.A = 12;
result.B = 42;
result.C = 0;
bool valid = result.Validate(); // == true