【问题标题】:Code Contracts: How do I supply a contract class for a generic interface?代码合同:如何为通用接口提供合同类?
【发布时间】:2010-01-27 23:01:43
【问题描述】:

我想为这个通用接口指定一个契约,使用代码契约:

interface IRandomWriteAccessible<T>
{
    T this[uint index] { set; }
    uint Length { get; }
}

文档说在为接口指定契约时使用ContractClass 属性。但是,编译器会抱怨这个:

[ContractClass(typeof(IRandomWriteAccessibleContract<T>))]
//             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^     <-- compiler error
interface IRandomWriteAccessible<T> { … }

[ContractClassFor(typeof(IRandomWriteAccessible<T>))]
//                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^          <-- compiler error
sealed class IRandomWriteAccessibleContract<T> : IRandomWriteAccessible<T> { … }

类型参数好像不能和属性一起使用。

如何为我的通用接口编写合同?还是代码合同无法做到这一点?

【问题讨论】:

  • 我还没有验证这一点,但是从您的属性用法中删除T,如下所示:[ContractClass(typeof(IRandomWriteAccessibleContract&lt;&gt;))]

标签: .net generics interface code-contracts


【解决方案1】:

正如其他 cmets 在此问题中所提到的,您应该从属性使用中删除泛型类型标识符,因为它无法在编译时解析:

[ContractClass(typeof(IRandomWriteAccessibleContract<>))] 

【讨论】:

  • 出于好奇,我在 C# 语言规范中查找了这一点:相关章节是 14.5.11(typeof 运算符)25.5(泛型:构造类型) ,如果其他人有兴趣。
  • 另外,如果你正在 typeof()'ing 的泛型类需要多个参数,你必须使用逗号;例如 typeof(YourType),其中 YourType 有两个类型参数。
【解决方案2】:

问得好,但您可以看到这个限制背后的技术原因,对吧?

不能指定ContractClass的原因是Blah&lt;T&gt;不是一个类。

如果您可以通过指定 T 的值来为具体类创建接口,即使我确信这是次优的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-12
    • 2019-01-17
    • 1970-01-01
    • 1970-01-01
    • 2022-07-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多