【问题标题】:Nested contracts for generic interfaces通用接口的嵌套合约
【发布时间】:2013-09-20 09:20:31
【问题描述】:

我可以有一个非通用接口的嵌套合同类型:

[ContractClass(typeof(Foo.FooContracts))]
public interface IFoo
{
    string Bar(object obj);
}

但是当我尝试使用通用接口做同样的事情时它会抱怨:

[ContractClass(typeof(Foo.FooContracts<>))]
public interface IFoo<T>
{
    string Bar(T obj);
}

警告是:

合约类 Foo+FooContracts`1 和类型 IFoo`1 必须具有相同的声明类型(如果有)。

如果我从 Foo 类中得到 FooContracts,它将在没有警告的情况下编译。

  • 为什么泛型接口存在这种限制?
  • 为什么非泛型的限制不存在?

【问题讨论】:

  • 作为一个实验,我将一个非泛型 FooContracts 嵌套在一个泛型 Foo&lt;T&gt; 类中,并按上述方式设置所有内容。除了您显示的消息之外,这现在还会生成“合同类 'Foo1+FooContracts' and the type 'IFoo1' 必须同意所有通用参数。”我想知道这是否是他们试图通过制定您找到的规则来避免的泥潭的开始。
  • @Damien:好主意!我认为这很有可能,因为它也解释了为什么它不会出现在非泛型接口中。

标签: c# generics interface code-contracts


【解决方案1】:

存在限制的原因是我们需要将合​​约从声明点复制到插入点,如果有通用的周边类,这会变得更加复杂。确实没有必要将契约类嵌套在我看到的其他类型中。

【讨论】:

    【解决方案2】:

    这段代码在我的机器上编译(VS2012,.NET 4.5)

    [ContractClass(typeof(Foo.FooContracts<>))]
    public interface IFoo<T> {
        string Bar(T obj);
    }
    
    [ContractClassFor(typeof(IFoo<>))]
    public class Foo {
        public class FooContracts<T> : IFoo<T> {
            public string Bar(T obj) {
                throw new NotImplementedException();
            }
        }
    }
    

    我添加了 ContractClassForAttribute,但我可以将其取出。

    edit:ContractClassForAttribute 也可以应用于外部或内部类。我不知道哪个是正确的,但是这两个位置都不影响编译

    【讨论】:

    • 如果我按照你的建议使用它: 1. 类型IFoo`1 指定类Foo+FooContracts`1 作为它的合同类,但该类不指向此类型. 2. Foo 应该是一个抽象类 3.Foo 被注释为接口IFoo`1 的契约,但不实现接口。 如果我将属性应用于内部类: 1. Foo 应该是抽象类 2. 合同类 Foo+FooContracts`1 和类型 IFoo`1 必须具有相同的声明类型(如果有)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多