C# 通用接口上的代码契约问题

C# 通用接口上的代码契约问题,c#,.net,generics,interface,code-contracts,C#,.net,Generics,Interface,Code Contracts,我遇到一个涉及通用接口合同的问题。我有两个通用接口,每个接口都有一个方法,该方法有一个前提条件(需要契约)。第一个接口的契约按预期工作:先决条件被传播到实现类,并且接口方法被适当地修饰(通过代码契约编辑器扩展)。未检测到第二个接口的约定,但两个接口/约定对之间的代码几乎相同 // // Example working as expected // [ContractClass(typeof(IExporterContract<>))] public interface IExpor

我遇到一个涉及通用接口合同的问题。我有两个通用接口,每个接口都有一个方法,该方法有一个前提条件(
需要
契约)。第一个接口的契约按预期工作:先决条件被传播到实现类,并且接口方法被适当地修饰(通过代码契约编辑器扩展)。未检测到第二个接口的约定,但两个接口/约定对之间的代码几乎相同

//
// 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);
    }
}  
//
//示例按预期工作
//
[合同类别(类型(出口合同))]
公共接口IExporter
地点:班级
{
//显示装饰“需要对象!=null”;合同分发
无效输出(TInput obj);
}
[ContractClassFor(类型(IExporter))]
抽象类IExporterContract:IExporter
地点:班级
{
公共作废导出(TInput obj)
{
Contract.Requires(obj!=null);
}
}
// 
//具有意外行为的示例
//
[合同类别(类型(IParserContract))]
公共接口IParser
where TOutput:类
{
//工作簿为Microsoft.Office.Interop.Excel.Workbook
//不显示装饰“需要工作簿!=null”;合同不分发
TOutput解析(工作簿);
}
[ContractClassFor(typeof(IParser))]
抽象类IParserContract:IParser
where TOutput:类
{
公共TOutput解析(工作簿)
{
Contract.Requires(工作簿!=null);
返回默认值(TOutput);
}
}  
请注意,
Microsoft.Office.Interop.
中的任何接口都会导致此行为。使用任何其他类型,一切都按预期工作。然而,我不知道这是为什么


编辑:由于正在编写合同(通过IL确认),因此这似乎是特定于代码合同编辑器扩展的。

我无法复制此内容。给出以下代码(以及您的示例):


你是对的,它确实出现在IL中;我没有检查。是否安装了代码契约编辑器扩展?我很想知道合同装饰是否为您展示。它没有为我展示任何有关
Parse
的内容。然而,当我将鼠标移到导出上时,它会显示“此成员没有合同”,这很奇怪。可能与最新的CC版本不兼容?
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;
}