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