具有虚方法的基类,只实现一个保护子句

时间:2010-11-24 15:32:51

标签: c# oop

如果您的基类定义如下:

public abstract class BaseMessageObject<T> where T : Entity
{        
  public string Message { get; set; }        
  public abstract BaseMessageObject<T> BuildMessage(T entity);
}

你有一个HTMLObjectMessages的基类,定义如下:

public abstract class HtmlMessageObject<T> : BaseMessageObject<T> 
   where T : Entity
{
  public override abstract BaseMessageObject<T> BuildMessage(T entity);
}

你有一个HtmlMessage的具体实现如下:

public class SocialSecurityVerificationHtmlMessageObject<T>:HtmlMessageObject<T>
   where T : SomeConcreteEntity
{
   public override BaseMessageObject<T> BuildMessage(T entity)
   {
      SocialSecurityVerificationHtmlMessageObject<T> message = 
            new SocialSecurityVerificationHtmlMessageObject<T>();            
      //do some stuff to build the message
   }
}

在基本MessageObject中放置保护子句是否有任何危害,如下所示:

public abstract class BaseMessageObject<T> where T : Entity
{        
   public string Message { get; set; }        
   public virtual BaseMessageObject<T> BuildMessage(T entity)
   {
      if (null == entity)
               throw new ArgumentNullException(entity)
      throw new NotImplemenetedException("");
   }
}

关于这个问题感觉不对。这应该重构吗?

3 个答案:

答案 0 :(得分:1)

我会这样做:

public abstract class BaseMessageObject<T> where T : Entity
{        
   public string Message { get; set; }        

   public BaseMessageObject<T> BuildMessage(T entity)
   {
        if (null == entity)
               throw new ArgumentNullException(entity)
        BuildMessageCore (entity);
   }

   protected abstract BaseMessageObject<T> BuildMessageCore(T entity);
}

答案 1 :(得分:0)

public class SocialSecurityVerificationHtmlMessageObject<T> : HtmlMessageObject<T>
    where T : SomeConcreteEntity

与基础冲突

public abstract class BaseMessageObject<T>  
    where T : Entity
不同的地方T.你不能声明2个不同的类型参数继承行

你可以做到这一点

public class SocialSecurityVerificationHtmlMessageObject<T> : HtmlMessageObject<SomeConcreteEntity> 
    where T : SomeConcreteEntity

但问题是你的基类永远不知道T究竟是什么。

答案 2 :(得分:0)

您可以使用code contract

[ContractClass(typeof(BaseMessageObjectContract<>))]
public abstract class BaseMessageObject<T> where T : Entity {         
  public string Message { get; set; }         
  public abstract BaseMessageObject<T> BuildMessage(T entity); 
}

[ContractClassFor(typeof(BaseMessageObject<>))]
abstract class BaseMessageObjectContract<T> : BaseMessageObject<T> 
  where T : Entity {
  public override BaseMessageObject<T> BuildMessage(T entity) { 
    Contract.Requires<ArgumentNullException>(entity != null);
    return null;
  }
}

你还应该enable runtime checking你的先决条件。