C# 通用接口的嵌套契约

C# 通用接口的嵌套契约,c#,generics,interface,code-contracts,C#,Generics,Interface,Code Contracts,我可以为非泛型接口使用嵌套合同类型: [ContractClass(typeof(Foo.FooContracts))] public interface IFoo { string Bar(object obj); } 但当我尝试用通用接口做同样的事情时,它会抱怨: [ContractClass(typeof(Foo.FooContracts<>))] public interface IFoo<T> { string Bar(T obj); } [

我可以为非泛型接口使用嵌套合同类型:

[ContractClass(typeof(Foo.FooContracts))]
public interface IFoo
{
    string Bar(object obj);
}
但当我尝试用通用接口做同样的事情时,它会抱怨:

[ContractClass(typeof(Foo.FooContracts<>))]
public interface IFoo<T>
{
    string Bar(T obj);
}
[ContractClass(typeof(Foo.FooContracts))]
公共接口IFoo
{
弦杆(T obj);
}
警告是:

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

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

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

此代码在我的机器上编译(VS2012、.NET 4.5)

[ContractClass(typeof(Foo.FooContracts))]
公共接口IFoo{
弦杆(T obj);
}
[ContractClassFor(typeof(IFoo))]
公开课Foo{
公共类:IFoo{
公共字符串条(T obj){
抛出新的NotImplementedException();
}
}
}
我为属性添加了ContractClassfor,但我可以将其删除


编辑:ContractClassForAttribute也可以应用于外部或内部类。我不知道哪一个是正确的,但这两个位置都不会影响编译。存在限制的原因是我们需要将契约从声明点复制到插入点,如果存在泛型的周围类,这将变得更加复杂。实际上没有必要在我看到的其他类型中嵌套契约类。

作为一个实验,我在一个泛型
Foo
类中嵌套了一个非泛型
FooContracts
,并按照上面的方式设置所有内容。除了您显示的消息外,现在还生成“合同类'Foo
1+FooContracts'和类型'IFoo
1'必须在所有通用参数上一致。”我想知道这是否是他们试图通过使用您找到的规则来避免陷入泥潭的开始。@Damien:好主意!我认为这是很有可能的,因为它也解释了为什么非泛型接口不会出现这种情况。Type
IFoo`1
指定类
Foo+FooContracts`1
作为其合同类,但该类不指向此类型。2.
Foo
应该是抽象类3。类
Foo
被注释为接口
IFoo`1
的契约,但没有实现接口。如果我将该属性应用于内部类:1
Foo
应该是抽象类2。合同类
Foo+FooContracts`1
和类型
IFoo`1
必须具有相同的声明类型(如果有)。
[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();
        }
    }
}