仅允许为特定类实现接口

问题描述 投票:0回答:7

是否可以只允许某些特定的类实现接口? 假设我创建了接口

IMyInterface
,并且我只希望从
UserControl
派生的类能够实现我的接口。这可能吗?

c# inheritance interface
7个回答
14
投票

您不能,但您可以通过向界面添加 Control 属性来实现类似的效果,并按照惯例使所有实现返回

this
。并不能解决你的问题,但会让实现者思考一下该接口是否真的属于那里。还允许界面用户以类型安全的方式检索控件,而无需进行强制转换。

interface IMyInterface
{
    void Foo();
    UserControl Control { get; }
}


class MyControl : UserControl, IMyInterface
{
    public void Foo()
    {
        // TODO: Write code here
    }

    UserControl IMyInterface.Control
    {
        get { return this; }
    }
}

更新

还有另一种解决方案——制作通用方法。界面本身不会受到限制,但操作方法会受到限制。例如,以下方法要求其参数既继承

UserControl
又实现
IMyInterface

void Bar<T>(T item)
  where T : UserControl, IMyInterface
{
    item.Width = 120;    // user control property
    item.Foo();          // IMyInterface method
}

11
投票

我意识到这是一篇旧帖子,但我必须准确解决这个问题。

您可以这样做:

class BaseClass { }

interface OnlyBaseClass<TSelf> where TSelf : BaseClass, OnlyBaseClass<TSelf>
{

}

class ChildClass : BaseClass, OnlyBaseClass<ChildClass> { }

class ImpostorClass : OnlyBaseClass<ImposterClass> { }

interface ImposterInterface : OnlyBaseClass<ImposterInterface > { }

尝试编译以上内容。您会注意到它无法编译(由于两个冒名顶替者,一个是类,一个是接口)。

TSelf的约束可以理解为:

TSelf必须:从BaseClass继承并且实现OnlyBaseClass<TSelf>

...只有继承自 BaseClass 并实现 OnlyBaseClass 的类型才能做到。

你可以聪明点,做以下事情:

class AdvancedImpostorClass : OnlyBaseClass<ChildClass> {}

...将编译。您可以通过在任何接受它们作为参数的方法中使用相同的约束来防止这些类型的冒名顶替者进入您的代码,如下所示:

public SomeMethod<TBaseAndInterface>(TBaseAndInterface value)
    where TBaseAndInterface: BaseClass, OnlyBaseClass<TBaseAndInterface>
{ }

这一切都是通过F-结合多态性的力量成为可能的。


3
投票

听起来你想要这样的东西:

abstract class IMyInterface : UserControl { }

当然,

IMyInterface
不再是一个合适的名称,但是任何派生自
IMyInterface
的类也将从
UserControl
派生,这将满足您的要求。


2
投票

这是不可能的。如果你能看到接口,你就可以实现它。


2
投票

不,没有办法将接口的实现限制为特定类型。为什么你需要这样做?为什么抽象的使用者关心实现该契约的具体类型?您的用例是什么?


1
投票

您描述的情况似乎适合“父类中的抽象方法”(此处为 userControl),除非该接口已存在用于其他目的。

如果没有默认主体,派生类将必须提供行为。


0
投票

从 C# 8 开始,接口的成员可能具有访问修饰符。因此,向接口添加

internal
成员而不提供默认实现,将阻止该程序集外部的类型实现它。这是基于类的类似解决方案,您可以在构造函数上放置访问修饰符以限制继承:

public interface IMyInterface
{
    internal void ExternalImplementationsDisabled();

    void MyMethod();
}

也可以通过将

internal
替换为
private protected
来隐藏此成员,使其在任何地方都无法访问:

public interface IMyInterface
{
    private protected void ExternalImplementationsDisabled();

    void MyMethod();
}

不幸的是,该解决方案并不将

IMyInterface
的实现限制为特定类,尽管它确实阻止了程序集外部的类型实现它。据我所知,这是防止类型实现接口的唯一方法。

© www.soinside.com 2019 - 2024. All rights reserved.