强制实现接口A的类也继承自从接口B派生的类型

时间:2014-05-14 07:10:27

标签: c# inheritance

我想要的是,如果A类实现了我的接口(B),我也希望A被强制实现从C类派生的接口/类型。

在代码中,结果如下所示:

public interface SomeInterface
{
    // implementing this interface forces the implementing class to also implement
    // a derived interface/type of SomeBaseInterface 
    void SomeMethod();
}

public interface SomeBaseInterface
{
    void SomeBaseMethod();
}

public interface SomeOtherInterface : SomeBaseInterface
{
    void SomeOtherMethod();
}

public class ImplementingClass : SomeInterface, SomeOtherInterface // <- if not
 // implementing an interface/type derived from SomeBaseInterface
 // this should not compile
{
    public void SomeMethod()
    {
    }

    public void SomeOtherMethod()
    {
    }

    public void SomeBaseMethod()
    {
    }
}

*编辑 它也可以'标记'SomeBaseInterface不能被类继承。这意味着只有另一个接口/抽象类可以继承它。不可能,请参阅C# Interfaces- only implement an interface in other interfaces

3 个答案:

答案 0 :(得分:1)

我不认为你可以在使用另一个界面时强制使用一个界面,除非你从另一个界面派生出一个界面。但是,您可以使用属性并设置单元测试,以便为您检查代码。

[MyInterfaceCheck(typeof(IMyBaseInterface))]
public interface IMyInterfaceA {...}

public interface IMyBaseInterface {...}

public interface IMyInterfaceB : IMyBaseInterface {...}

public class MyClass : IMyInterfaceA, IMyInterfaceB {...}

该属性将简单地定义为:

public class MyInterfaceCheckAttribute : Attribute
{
    public MyInterfaceCheckAttribute(Type typeThatShouldAlsoBeInherited)
    {
        if (!typeThatShouldAlsoBeInherited.IsInterface)
        {
            throw new ArgumentException("Incorrect type being used with MyInterfaceCheckAttribute.");
        }
        TypeThatShouldBeInherited = typeThatShouldAlsoBeInherited;
    }

    public Type TypeThatShouldBeInherited { get; private set; }
}

单元测试:

[TestMethod]
public void CheckInterfaceInheritenceTest()
{
    Dictionary<Type, MyInterfaceCheckAttribute> typesToCheck = new Dictionary<Type, MyInterfaceCheckAttribute>();
    foreach (Type typeToCheck in Assembly.GetExecutingAssembly().GetTypes())
    {
        MyInterfaceCheckAttribute myAtt = typeToCheck.GetCustomAttribute(typeof(MyInterfaceCheckAttribute), true) as MyInterfaceCheckAttribute;
        if (myAtt != null)
        {
            typesToCheck.Add(typeToCheck, myAtt);
        }
    }

    foreach (Type typeToCheck in Assembly.GetExecutingAssembly().GetTypes())
    {
        Type[] interfaces = typeToCheck.GetInterfaces();

        foreach (KeyValuePair<Type, MyInterfaceCheckAttribute> kvp in typesToCheck)
        {
            if (interfaces.Contains(kvp.Key) && !interfaces.Contains(kvp.Value.TypeThatShouldBeInherited))
            {
                Assert.Fail("The type " + typeToCheck.Name + " should inherit the interface " + kvp.Value.TypeThatShouldBeInherited.Name);
            }
        }
    }
}

答案 1 :(得分:1)

显而易见的方法是拥有SomeInterface : SomeBaseInterface并拥有ImplementingClass : SomeInterface, SomeOtherInterface。你能澄清一下为什么不可能吗?这会强制实现SomeInterface的类至少继承自SomeBaseInterface,并且可以通过继承SomeOtherInterface来扩展它。

唯一的区别是它可能没有继承SomeOtherInterface,但是对于所有你知道的界面无论如何都不能包含任何内容。

EmptyInterface

interface SomeOtherOtherInterface : SomeBaseInterface {
}

我建议如果你想让类继承上面的接口,而不是SomeBaseInterface你做错了什么。还有一个含义是你指定了更多未知方法的存在,这也是一种可疑的方式。

是否有些东西应放在SomeBaseInterface但是没有?例如,在一个派生界面中有void SendEmail,而在void SendFax明显像SendMessage这样的SomeBaseInterface一直在{{1}}吗?

但显然,如果你想继续使用单元测试方法。

答案 2 :(得分:0)

只是为了明确继承和接口。我们假设我们有接口IAnimalIFeline

interface IAnimal
{
    void Eat();
}

interface IFeline: IAnimal
{
    void Purr();
}

现在让我们定义类Cat并要求它实现接口IFeline

class Cat: IFeline
{

}

编译代码:

'Cat' does not implement interface member 'IFeline.Purr()'
'Cat' does not implement interface member 'IAnimal.Eat()'

现在很明显,编译器希望我们在类IAnimal中实现接口IFelineCat