泛型接口中的代码合约问题

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.* 中的任何接口都会导致此行为。使用任何其他类型,一切都按预期工作。我不知道这是为什么。
编辑:正如Porges指出,合同正在编写(通过IL确认),因此这似乎是特定于代码合同编辑器扩展的。
1个回答

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

你说得对,它确实在IL中显示出来了;我之前没有检查过。你安装了Code Contracts Editor Extension吗?我很想看看你是否能看到合同修饰。 - Matt Burton
1
对于“Parse”,它没有显示任何内容。但是当我将鼠标悬停在“Export”上时,它会显示“此成员没有合同”,这很奇怪。也许与最新的CC版本不兼容? - porges

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接