开发者

Allowing implementing interface only for specific classes

Is it possible to permit only some specific classes to implem开发者_如何学运维ent an iterface? Let's say that I created interface IMyInterface and I want only classes which derive from UserControl to have an ability to implement my interface. Is this possible?


You cannot, but you can achieve something similar by adding a Control property to your interface, and by-convention making all the implementations return this. Doesn't solve your problem, but makes the implementer think a bit whether or not the interface really belongs there. Also allows the user of the interface to retrieve the control in a type-safe manner without casting.

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


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

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

UPDATE

There is also another solution - making a generic method. The interface itself will not be restricted, but the method operating will be. For example, the following method requires that its parameter both inherits UserControl and implements IMyInterface:

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


I realize this is an old post, but I had to solve exactly this problem.

Here is how you can do it:

class BaseClass { }

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

}

class ChildClass : BaseClass, OnlyBaseClass<ChildClass> { }

class ImpostorClass : OnlyBaseClass<ImposterClass> { }

interface ImposterInterface : OnlyBaseClass<ImposterInterface > { }

Try to compile the above. You will notice that it doesn't compile (due to the two impostors, one a class, one an interface).

The constraint on TSelf can be understood as:

TSelf must: Inherit from BaseClass and implement OnlyBaseClass<TSelf>

...which only a type inheriting from BaseClass and implementing OnlyBaseClass could do.

You could be clever, and do the following:

class AdvancedImpostorClass : OnlyBaseClass<ChildClass> {}

... which will compile. You could prevent these types of impostors from ever getting through into your code by using the same constraints in any methods that accept them as arguments though, like so:

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

This is all made possible through the power of F-Bound Polymorphism.


It sounds like you want something like this instead:

abstract class IMyInterface : UserControl { }

Of course IMyInterface is no longer an appropriate name, but any class that derives from IMyInterface would also derive from UserControl, which would satisfy your requirements.


This is not possible. If you can see the interface, you can implement it.


No, there is no way of restricting the implementation of an interface to specific types. Why would you need to? Why does the consumer of an abstraction care about the concrete types that implement that contract? What is your use case?


The case you describe seems to fit an "abstract method in your parent class" (here userControl) , unless the interface already exists for other purposes.

Without default body, derivated classes will have to provide a behavior.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜