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

本文关键字:接口 类型 继承 派生 实现 | 更新日期: 2023-09-27 18:03:27

我想要的是,如果类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#接口-只在其他接口中实现一个接口

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

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

[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);
            }
        }
    }
}

明显的方法是有SomeInterface : SomeBaseInterfaceImplementingClass : SomeInterface, SomeOtherInterface。你能解释一下为什么不可能吗?这强制实现SomeInterface的类至少继承SomeBaseInterface,这可以通过继承SomeOtherInterface来扩展。

唯一的区别是可以不继承SomeOtherInterface,但无论如何,接口可以不包含任何内容。

EmptyInterface:

interface SomeOtherOtherInterface : SomeBaseInterface {
}

我建议如果你想允许类从上面的接口继承,而不是SomeBaseInterface你做错了。这也意味着你指定了更多未知方法的存在,这也有点可疑。

是有东西你应该放在SomeBaseInterface,但没有?是否有,例如,在一个派生接口中的void SendEmail和在另一个派生接口中的void SendFax,而显然像SendMessage这样的东西应该一直在SomeBaseInterface中?

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

只是为了说清楚继承和接口。让我们假设有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()'

现在很明显,编译器希望我们在Cat类中实现IAnimalIFeline两个接口。