2010-11-24 10 views
0

を実装:ベースの仮想メソッドを持つクラスのみ次のように定義された基本クラスを持っている場合は、ガード句

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

次のようにBase 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(""); 
    } 
} 

これについては何か間違っています。これをリファクタリングする必要がありますか?

答えて

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

+1:[テンプレートメソッドパターン](http://en.wikipedia.org/wiki/Template_method_pattern)を公正に使用しているようです。 – rsenna

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

public abstract class BaseMessageObject<T> 
    where T : Entity 

T異なっているベースとの競合です。 uがuは、この

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

を行うことができます2つの異なるタイプのパラメータ継承されたライン

を宣言することはできませんが、問題は、あなたのベースクラスはTが本当に何であるかを知ることはありませんです。

+0

間違っています。 'SomeConcreteEntity'が' Entity'から継承しても矛盾はありません。 –

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あなたの前提条件の。

関連する問題