Inheritance 带有代码契约和接口继承的奇怪警告/错误

Inheritance 带有代码契约和接口继承的奇怪警告/错误,inheritance,c#-4.0,interface,code-contracts,Inheritance,C# 4.0,Interface,Code Contracts,作为主题,我在代码契约和接口中遇到了严重警告/错误。 这里是我的场景 主接口 [ContractClass(typeof(DTOInfoContract))] public interface IDTOInfo { int ID { get; } string Description { get; } string LinkText { get; } string Title { get; } void DTOInit(int id, s

作为主题,我在代码契约和接口中遇到了严重警告/错误。 这里是我的场景

主接口

[ContractClass(typeof(DTOInfoContract))]
public interface IDTOInfo
{
    int ID { get; }
    string Description { get; }        
    string LinkText { get; }
    string Title { get; }

    void DTOInit(int id, string title, string descr, string linkText);
}
二级接口

[ContractClass(typeof(DTONewsContract))]
public interface IDTONews : IDTOInfo
{    
}

[ContractClass(typeof(DTOPromoContract))]
public interface IDTOPromo : IDTOInfo
{                
    string Photo { get; }

    void DTOPromoInit(int id, string title, string descr, string linkText, string Photo);
然后是我的合同

[ContractClassFor(typeof(IDTOInfo))]
public abstract class DTOInfoContract : IDTOInfo
{
    int IDTOInfo.ID
    {
        get { Contract.Ensures(Contract.Result<int>() > 0, "Returned value is out of Range"); return default(int); }
    }

    string IDTOInfo.Description
    {
        get { Contract.Ensures(!String.IsNullOrEmpty(Contract.Result<string>()), "Returned value is out of Range"); return default(string); }
    }

    string IDTOInfo.LinkText
    {
        get { Contract.Ensures(!String.IsNullOrEmpty(Contract.Result<string>()), "Returned value is out of Range"); return default(string); }
    }

    string IDTOInfo.Title
    {
        get { Contract.Ensures(!String.IsNullOrEmpty(Contract.Result<string>()), "Returned value is out of Range"); return default(string); }
    }

    void IDTOInfo.DTOInit(int id, string title, string descr, string linkText)
    {
        Contract.Requires<ArgumentOutOfRangeException>(id > 0, "id has no valid value");
        Contract.Requires<ArgumentOutOfRangeException>(!String.IsNullOrEmpty(title), "titolo has no valid value");
        Contract.Requires<ArgumentOutOfRangeException>(!String.IsNullOrEmpty(descr), "descr has no valid value");
        Contract.Requires<ArgumentOutOfRangeException>(!String.IsNullOrEmpty(linkText), "linkText has no valid value");
    }
}


}


[ContractClassFor(typeof(IDTONews))]
public abstract class DTONewsContract : IDTONews
{
    int IDTOInfo.ID
    {
        get { Contract.Ensures(Contract.Result<int>() > 0, "Returned value is out of Range"); return default(int); }
    }

    string IDTOInfo.Description
    {
        get { Contract.Ensures(!String.IsNullOrEmpty(Contract.Result<string>()), "Returned value is out of Range"); return default(string); }
    }

    string IDTOInfo.linkText
    {
        get { Contract.Ensures(!String.IsNullOrEmpty(Contract.Result<string>()), "Returned value is out of Range"); return default(string); }
    }

    string IDTOInfo.Title
    {
        get { Contract.Ensures(!String.IsNullOrEmpty(Contract.Result<string>()), "Returned value is out of Range"); return default(string); }
    }

    void IDTOInfo.DTOInit(int id, string title, string descr, string linkText)
    {
        Contract.Requires<ArgumentOutOfRangeException>(id > 0, "id has no valid value");
        Contract.Requires<ArgumentOutOfRangeException>(!String.IsNullOrEmpty(title), "title has no valid value");
        Contract.Requires<ArgumentOutOfRangeException>(!String.IsNullOrEmpty(descr), "descr has no valid value");
        Contract.Requires<ArgumentOutOfRangeException>(!String.IsNullOrEmpty(linkText), "linkText has no valid value");
    }
}


[ContractClassFor(typeof(IDTOPromo))]
public abstract class DTOPromoContract : IDTOPromo
{        
    string IDTOPromo.Photo
    {
        get { Contract.Ensures(!String.IsNullOrEmpty(Contract.Result<string>()), "Returned value is out of Range"); return default(string); }
    }        

    void IDTOPromo.DTOPromoInit(int id, string title, string descr, string linkText, string photo)
    {
        Contract.Requires<ArgumentOutOfRangeException>(id > 0, "id has no valid value");
        Contract.Requires<ArgumentOutOfRangeException>(!String.IsNullOrEmpty(title), "title has no valid value");
        Contract.Requires<ArgumentOutOfRangeException>(!String.IsNullOrEmpty(descr), "descr has no valid value");                  
        Contract.Requires<ArgumentOutOfRangeException>(!String.IsNullOrEmpty(linkText), "linkText has no valid value");
    }

    int IDTOInfo.ID
    {
        get { Contract.Ensures(Contract.Result<int>() > 0, "Returned value is out of Range"); return default(int); }
    }

    string IDTOInfo.Description
    {
        get { Contract.Ensures(!String.IsNullOrEmpty(Contract.Result<string>()), "Returned value is out of Range"); return default(string); }
    }

    string IDTOInfo.LinkText
    {
        get { Contract.Ensures(!String.IsNullOrEmpty(Contract.Result<string>()), "Returned value is out of Range"); return default(string); }
    }

    string IDTOInfo.Title
    {
        get { Contract.Ensures(!String.IsNullOrEmpty(Contract.Result<string>()), "Returned value is out of Range"); return default(string); }
    }

    void IDTOInfo.DTOInit(int id, string title, string descr, string linkText)
    {
        Contract.Requires<ArgumentOutOfRangeException>(id > 0, "id has no valid value");
        Contract.Requires<ArgumentOutOfRangeException>(!String.IsNullOrEmpty(title), "title has no valid value");
        Contract.Requires<ArgumentOutOfRangeException>(!String.IsNullOrEmpty(descr), "descr has no valid value");
        Contract.Requires<ArgumentOutOfRangeException>(!String.IsNullOrEmpty(linkText), "linkText has no valid value");
    }
}
但是,如果我试图删除IDTONews和IDTOPromo契约类中的IDTOInfo方法和属性,那么错误如下

warning CC1076: Contract class DTOPromoContract cannot define contract for method IDTOInfo.get_ID as its original definition is not in type IDTOPromo. Define the contract on type IDTOInfo instead.
Error   40 'DTOPromoContract' does not implement the member of interface 'IDTOInfo.Description' 
这是一种奇怪的情况,不是吗? 是否有一种解决方案可以将代码契约和接口与前面的场景进行最佳组合


谢谢大家!

契约类应该只指定它们所附加到的接口的行为,而不是任何基本接口


因此,在
DTOPromoContract
DTONewsContract
中,从
IDTOInfo
继承的所有方法都应该是
abstract
。(所有接口契约类也应该是
abstract

我现在无法尝试,但是当您使用
公共抽象类DTOPromoContract:DTOInfoContract,IDTOPromo
时会发生什么情况?@Henk Holterman:谢谢您的回答,我已经尝试了您的解决方案,但现在警告是无效的“警告CC1066:类'DTOPromoContract'被注释为接口'IDTOPromo'的约定,并且不能有System.Object以外的显式基类。”我认为这是正确的:-)也许我不明白,你的意思是这样的吗?在DTONewsContract:abstract int IDTOInfo.ID{get…}??它不是该类的有效修饰符。请您解释一下您的答案好吗?谢谢!您必须实现整个接口,当然包括基本接口,否则C#不满意。但对于契约,您只希望为实际注释的顶级接口指定契约。对于继承的接口方法,JU不要让C#编译器自动实现它们,抛出NotImplemented。@ManuelFahndrich:您根本不需要实现基接口,因为您的合同类将是抽象的。@Porges,通过实现,我的意思是有一个使C#编译器满意的声明。因此,是的,继承接口成员的抽象声明是曼努埃尔法汉德里奇:酷,只是澄清一下:)