2015-05-27 8 views
0

Я хотел бы использовать CodeContracts для проверки некоторых конкретных реализаций универсального интерфейса. я имел основной общий интерфейсCodeContracts для определенного общего интерфейса

public interface IEnityMap<in TSource,out TDest> 
{ 
    TDest Map(TSource); 
} 

Я хочу, чтобы определить CodeContracts для некоторых конкретных интерфейсов. Я пытаюсь сделать что-то вроде этого:

[ContractClass(typeof(ContractClass))] 
public interface ISpecific: IEntityMap<SourceClass,DestClass>{} 

[ContractClassFor(typeof(ISpecific))] 
public abstract class ContractClass: ISpecific 
{ 
public DestClass Map(SourceClass source) 
{ 
    Contract.Requires(source.SomeProperty!= null); 
    //Other checks 
    return default(DestClass); 
} 
} 

Мой класс Mapping реализует общий интерфейс - IEntityMap <,> (не ISpecific) и этот контракт делает `t работу.

+0

Было бы сложно определить '.SomeProperty' здесь. Но вы можете легко попробовать это и узнать. –

+0

Модульные тесты показали, что такой контракт не работает, даже если класс реализует интерфейс ISpecific –

ответ

0

Как я понимаю из ваших образцов кода вы получаете более специализированный интерфейс, где у вас больше ограничений на месте, чем в общем интерфейсе. Согласно документации (и основополагающему принципу Liskov substiution), просто не разрешено иметь больше ограничений в подклассе или более специализированном интерфейсе.

Вы должны получить сообщение об ошибке, как

"... implements interface method ... thus cannot add Requires" 

Что вы могли сделать, это попытаться бросить типы к конкретным типам, а затем утверждают вашу конкретную реализацию в производном (реферат) базового класса , Однако наличие интерфейсов, которые ведут себя по-разному в зависимости от переданных значений, может быть подвержено ошибкам и вызывать непредвиденные ошибки времени выполнения.

С уважением, Ronald