C# 使验证通用化

C# 使验证通用化,c#,.net,vb.net,generics,open-closed-principle,C#,.net,Vb.net,Generics,Open Closed Principle,我有下面的C代码。在这里,验证保持在类之外,以满足开-闭原则。这很好用。但挑战是——验证不是通用的。它特定于员工类别(例如,员工的生日)。如何使所有对象(DateOfBirthRuleForAnyObject)的验证通用化 注意:使泛型使类型独立 注:我还有NameLengthroleForEmployee验证。未来可能会有新的验证 编辑 通用方法示例: 代码 类程序 { 静态void Main(字符串[]参数) { 员工=新员工(); employee.DateOfBirth=DateTime

我有下面的C代码。在这里,验证保持在类之外,以满足开-闭原则。这很好用。但挑战是——验证不是通用的。它特定于员工类别(例如,员工的生日)。如何使所有对象(DateOfBirthRuleForAnyObject)的验证通用化

注意:使泛型使类型独立


注:我还有NameLengthroleForEmployee验证。未来可能会有新的验证

编辑

通用方法示例:

代码

类程序
{
静态void Main(字符串[]参数)
{
员工=新员工();
employee.DateOfBirth=DateTime.Now;
employee.Name=“Lijo”;
DateOfBirthroleForEmployee dobRule=新
员工的出生日期();
NameLengthroleForEmployee nameRule=新
NameLengthroleForEmployee();
EmployeeManager EmployeeManager=新的EmployeeManager();
employeeManager.AddRules(dobRule);
employeeManager.AddRules(nameRule);
bool result=employeeManager.validateEntity(员工);
控制台写入线(结果);
Console.ReadLine();
}
}
公共界面的开放性
{
}
公共接口病毒
{
bool是有效的(潜在实体);
}
员工的Birthrule公开课日期:IRule
{
公共bool有效(员工实体)
{

返回(entity.DateOfBirth.Year挑战是让您的规则知道要验证哪种类型的属性。您可以通过实现一个接口来实现这一点,该接口只提供SLaks建议的属性,或者通过动态查询它,或者通过提供一个具体的规则类来提供有关如何访问给定属性的更多信息,例如。:

class NameRule<T> : IRule<T>  
{
    private Func<T, string> _nameAccessor;

    public NameRule(Func<T, string> nameAccessor)
    {
        _nameAccessor = nameAccessor;
    }

    public bool IsValid(T instance)
    {
        return _nameAccessor(instance).Length > 10;
    }
}
类名称规则:IRule
{
专用函数名访问器;
公共名称规则(Func nameAccessor)
{
_nameAccessor=nameAccessor;
}
公共bool是有效的(T实例)
{
返回_nameAccessor(实例)。长度>10;
}
}
这当然可以通过以下方式使用:

NameRule<Employee> employeeNameRule = new NameRule<Employee>(x => x.name);
employeeManager.addRule(employeeNameRule);
NameRule employeeNameRule=newnamerule(x=>x.name);
employeeManager.addRule(employeeNameRule);

挑战在于让您的规则知道要验证哪种类型的属性。您可以通过实现一个接口来实现这一点,该接口只提供SLaks建议的属性,或者通过动态查询它,或者通过提供一个具体的规则类来提供有关如何访问给定属性的更多信息,例如:

class NameRule<T> : IRule<T>  
{
    private Func<T, string> _nameAccessor;

    public NameRule(Func<T, string> nameAccessor)
    {
        _nameAccessor = nameAccessor;
    }

    public bool IsValid(T instance)
    {
        return _nameAccessor(instance).Length > 10;
    }
}
类名称规则:IRule
{
专用函数名访问器;
公共名称规则(Func nameAccessor)
{
_nameAccessor=nameAccessor;
}
公共bool是有效的(T实例)
{
返回_nameAccessor(实例)。长度>10;
}
}
这当然可以通过以下方式使用:

NameRule<Employee> employeeNameRule = new NameRule<Employee>(x => x.name);
employeeManager.addRule(employeeNameRule);
NameRule employeeNameRule=newnamerule(x=>x.name);
employeeManager.addRule(employeeNameRule);

听起来你想要一个
IWasBorn
接口。我也有NameLengthroleForEmployee验证。将来可能会有新的验证。因此呢?你想要什么?
动态的
?所以IWasBorn将不能满足我的要求,因为还有一个与名称相关的验证。所以,制作更多的接口。听起来你想要什么一个
IWasBorn
接口。我也有NameLengthroleForEmployee验证。将来可能会有新的验证。因此,什么?你要求什么?
dynamic
?因此IWasBorn将无法满足我的要求,因为还有与名称相关的验证。因此,制作更多的接口。