开发者

Base class with virtual method and only implementing a guard clause

If you have a base class defined as follows:

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

and you have a base class for HTMLObjectMessages defined as follows:

public abstract class HtmlMessageObject<T> : BaseMessageObject<T> 
   where T : Entity
{
  public override abstract BaseMessageObject&l开发者_运维知识库t;T> BuildMessage(T entity);
}

and you have a concrete implementation of the HtmlMessage as follows:

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
   }
}

Is there any harm in placing guard clauses in the base MessageObject as follows:

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("");
   }
}

Something about this feels wrong. Should this be refactored?


I would do it like this:

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);
}


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

is conflict with base which is

public abstract class BaseMessageObject<T>  
    where T : Entity

different where T . u can't declare 2 different type parameter inherited line

u can do this

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

but the problem is your base class will never know what T really is.


You can use a 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;
  }
}

You should also enable runtime checking of your preconditions.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜