检索基类中的子类类型?

时间:2010-02-07 03:41:06

标签: c# validation inheritance subclass

我正在尝试使用Microsoft企业验证方法在我的实体中执行验证。在我的基类中,我有以下方法:

public class BaseEntity
{
  public bool IsValid()
  {
     return Validate().IsValid;
  }

  public ValidationResults Validate()
  {
     return Validation.Validate<this.GetType()>(this);
}

这个问题是,即使BaseEntity的子类调用IsValid,this.GetType()也总是返回BaseEntity,而不是Subclass的类型。我不想为每个实体重写这个代码,因为这似乎非常不喜欢。还有其他办法吗?

我确实有一个受保护变量受保护的Type _validationType的想法,并且在每个实体中将它设置为该实体的.GetType值,但似乎必须有更好的方法来执行此操作。

更新
显然没关系。 this.GetType()似乎正如我所希望的那样工作。不知道为什么以前没有。

我还将Validate()方法更改为使用以下代码:

 return ValidationFactory.CreateValidator(this.GetType()).Validate(this);

5 个答案:

答案 0 :(得分:2)

它的very un-OO like基类可以了解有关子类的任何信息。这有效的方式。

如果您想了解有关子类的信息,则需要覆盖此方法。

答案 1 :(得分:2)

当您使用O / RM映射器(如LINQ to SQL,NHibernate或LINQ to Entities(ADO.NET实体框架))时,我会采用另一种验证方法。我会让实体完全清除验证(因此没有BaseEntity.Validate()。您可以将此验证逻辑移动到ObjectContext(EF)/ DataContext(L2S)/ Session(NH)并在数据库提交期间触发验证查看下面的LINQ to SQL示例:

public partial class NorthwindDataContext
{
    public override void SubmitChanges(ConflictMode failureMode)
    {
        var invalidResults = (
            from entity in this.GetChangedEntities()
            let type = entity.GetType()
            let validator = ValidationFactory.CreateValidator(type)
            let results = validator.Validate(entity)
            where !results.IsValid
            from result in results
            select result).ToArray();            

        if (invalidResults.Length > 0)
        {
            // You should define this exception type
            throw new ValidationException(invalidResults);
        }

        base.SubmitChanges(failureMode);
    }

    private IEnumerable<object> GetChangedEntities()
    {
        ChangeSet changes = this.GetChangeSet();
        return changes.Inserts.Concat(changes.Updates);
    }
}

如果您的实体无效,将抛出ValidationException。您可以捕获该特定异常并迭代您在其上定义的InvalidResults属性。

当您需要更多信息时,我建议您阅读this文章。它还描述了如何使用Entity Framework执行此操作。

祝你好运。

答案 2 :(得分:1)

除了关于验证的所有内容之外,还有一种方法可以编写基类'方法,让它知道调用它的实际子类类型。

嗯......一种假装的方式,至少(没有违反任何OO规则,加布里埃尔)。它非常优雅,效果非常好:

public ValidationResults Validate<TEntity>(this TEntity e) where TEntity : BaseEntity
{
   return Validation.Validate<TEntity>(e);
}

扩展方法的一大好处......:)

答案 3 :(得分:0)

您可以使IsValid()Validate()成为虚拟方法,以便在子类中提供一些自定义定义。

答案 4 :(得分:0)

将类型逻辑移出BaseEntity更清晰。

public class BaseEntity
{
    public bool IsValid()
    {
        return Validate().IsValid;
    }

    public ValidationResults Validate()
    {
        return Validation.Validate(this);
    }
}
public class Validation
{
    public static ValidatorResults Validator<T>( T entity )
        where T : BaseEntity
    {
        return ValidationFactory.CreateValidator(entity.GetType()).Validate(entity);
    }
}
相关问题