2012-02-01 3 views
3

У меня возникла проблема с контрактами на общий интерфейс. У меня есть два общих интерфейса, каждый из которых имеет единственный метод, который имеет одно предварительное условие (контракт Requires). Контракт для первого интерфейса работает так, как ожидалось: предварительное условие распространяется на классы реализации, а метод интерфейса оформляется соответствующим образом (через расширение редактора кода контракта). Контракт для второго интерфейса не обнаружен, но код почти идентичен между двумя парами интерфейса/контракта.Проблема с кодовыми контрактами на общий интерфейс

// 
// Example working as expected 
// 

[ContractClass(typeof(IExporterContract<>))] 
public interface IExporter<in TInput> 
    where TInput : class 
{ 
    // Shows adornment "requires obj != null"; contracts propogate 
    void Export(TInput obj); 
} 

[ContractClassFor(typeof(IExporter<>))] 
abstract class IExporterContract<TInput> : IExporter<TInput> 
    where TInput : class 
{ 
    public void Export(TInput obj) 
    { 
     Contract.Requires(obj != null); 
    } 
} 


// 
// Example with unexpected behavior 
// 

[ContractClass(typeof(IParserContract<>))] 
public interface IParser<out TOutput> 
    where TOutput : class 
{ 
    // Workbook is Microsoft.Office.Interop.Excel.Workbook 

    // Does not show adornment "requires workbook != null"; contracts do not propogate 
    TOutput Parse(Workbook workbook); 
} 

[ContractClassFor(typeof(IParser<>))] 
abstract class IParserContract<TOutput> : IParser<TOutput> 
    where TOutput : class 
{ 
    public TOutput Parse(Workbook workbook) 
    { 
     Contract.Requires(workbook != null); 
     return default(TOutput); 
    } 
} 

Следует отметить, что любой интерфейс в Microsoft.Office.Interop.* вызывает подобное поведение. Используя любой другой тип, все работает так, как ожидалось. Однако я не знаю, почему это так.

EDIT: в Porges pointed out, договоры записываются (подтверждается с помощью IL), так что это, кажется, специфичные для расширения редактора кода контрактов.

ответ

2

Я не могу воспроизвести это. Учитывая этот код (вместе с вашим примером):

class Program 
{ 
    static void Main(string[] args) 
    { 
     var g = new Bar(); 
     g.Parse(null); 
     var f = new Foo(); 
     f.Export(null); 
    } 
} 

public class Foo : IExporter<Foo> 
{ 
    public void Export(Foo obj) 
    { 
    } 
} 
public class Bar : IParser<Bar> 
{ 
    public Bar Parse(Workbook workbook) 
    { 
     return null; 
    } 
} 

Контракт распространяется, как и ожидалось (декомпилированы через отражатель):

public Bar Parse(Workbook workbook) 
{ 
    __ContractsRuntime.Requires(workbook != null, null, "workbook != null"); 
    return null; 
} 
+0

Вы правы, это проявляется в IL; Я не проверял. У вас есть расширение редакторов Code Contracts? Мне любопытно узнать, появятся ли у вас украшения для контрактов. –

+1

Это не показывает мне ничего для 'Parse'. Однако, когда я нажимаю над «Экспорт», он говорит: «У этого участника нет контрактов», что странно. Может быть, есть некоторая несовместимость с последней версией CC? – porges

Смежные вопросы