为接口强制使用某种类型?

时间:2012-03-26 08:16:29

标签: c# inheritance

我的一个应用程序中有几个控件,它们都显然扩展了Control类。

我需要其中的几个来拥有一些共享接口,所以我创建了一个涵盖共享功能的接口。

有什么方法可以强制我的界面只能被赋予Control的子类?

即。 (伪)

interface IEmbed

class MyControl1 : Control, IEmbed

class MyControl2 : Control, IEmbed

class MyClass : IEmbed

理想情况下,我希望编译器在这里失败,因为MyClass尝试实现IEmbed,即使它不是控件。

我是以错误的方式解决这个问题还是有办法强制执行此行为?

修改

我被问到为什么要强制执行此行为。

我有一个方法,我想采取任何IEmbed实现,并将其作为子控件添加到另一个元素。

这一切都很好,但是Controls.Add()拒绝接受一个I​​Embed对象,这不会编译。

我想如果我告诉编译器实现IEmbed的任何东西都必须是一个控件,它可能有用吗?

6 个答案:

答案 0 :(得分:6)

不,在编译时无法强制执行此操作。

可以在运行时通过在使用obj is Control作为obj实例之前对IEmbed进行框架代码测试来强制执行它。

更新:根据评论的反馈,看起来一个好的解决方案是继承中级abstract class EmbedControl : Control并让您的方法接受EmbedControl而不是IEmbed(在这种情况下,实际上不需要保留接口,因为您只需在基类中使用abstract方法。)

虽然上述方法可以很好地工作,但在某些情况下,强制“客户”类的实现者从您自己的中间类派生,即使您需要它们从“基类”派生{{1} } 同时。在这种情况下,另一种好的方法是使用泛型:

Control

答案 1 :(得分:5)

如果您需要执行此类检查,我建议您检查一下您的设计。界面只是一个契约,并没有对可以遵守它的内容施加限制。如果类型很重要,那么您应该尝试不同的方法,例如基类。 如何使用需要继承者来实现接口方法的抽象类(您可以在其中指定类型约束)?

interface IInterface
{
    void Method1();
    int Property1 { get; }
}

abstract class BaseClass: Control, IInterface
{
    public abstract void Method1();
    public abstract int Property1 { get; }
}

这只能确保从BaseClass派生的任何类都是Control和implements IInterface。

答案 2 :(得分:2)

我认为没有办法强制执行这样的操作 - 但我认为你真的不需要,因为你可以在运行时检查你的接口实例是否为Control。

但是:alternativley只使用抽象类(派生自Control)而不是接口:

abstract class EmbedControl
   : Control
{
   // your abstract members
}

class MyControl1 : EmbedControl

答案 3 :(得分:0)

什么不使用声明而检查T是控制?

另外,我同意上面写的内容,为什么界面应该是一种类型?这似乎是一个糟糕的设计,你知道你以后会将你的界面重新投入控件......

答案 4 :(得分:0)

实际上我无法想象为什么你需要它,但是Control是IComponent的后代。 也许你应该继承那个?

答案 5 :(得分:0)

嗯,我提供的解决方案非常难看,但在编译时失败了。

public interface IEmbed<T> where T: Control
{
}

public class A :Control, IEmbed<A>
{
}

//this fails at compile time as B does not inherit from Control class.
public class B : IEmbed<B>
{
}