简体   繁体   中英

Is there any way to create a public .NET interface which can't be implemented outside of it's assembly?

In order to maintain binary backwards compatibility in .NET, you generally can't add new abstract methods to public classes and interfaces. If you do, then code built against the old version of the assembly that extends/implements your class/interface will fail at runtime because it fails to fully extend/implement the new version. For classes, however, there is a handy workaround:

public abstract class Foo {
    internal Foo() { }
}

Because Foo's constructor is internal, no-one outside of my assembly can extend Foo. Thus, I can add new abstract methods to Foo without worrying about backward compatibility since I know that no class in another assembly can extend Foo.

My question is, is there a similar trick for interfaces? Can I create a public interface and somehow guarantee that no one outside of my assembly will be able to create an implementation of it?

No, you can't do that. But then, considering that the point of an interface is to define the behavior of an implementation by defining a contract, that makes sense.

What you can do, however, is create an internal interface that inherits from your public interface :

public interface IPublicInterface {
    /* set-in-stone method definitions here */
}

internal interface IChildInterface : IPublicInterface  {
    /* add away! */
}

This should prevent any backwards compatibility issues with other assemblies while still allowing you to hide additional methods.

The downside, of course, is that you would have to remember to cast as IChildInterface when you need those, rather than simply being able to use it as an IPublicInterface

In all honesty, though, if you really wanted to define some assembly-only functionality while still requiring that the end user define their own implementations for some methods, then your best bet is probably an abstract class.

No, you can't.

But since in IL an interface is essentially just a pure abstract class (ie one without any implementation at all), you can use the technique you've already described and it will be practically the same.

As noted, keep in mind that this approach does restrict your type to inheriting just the fake "abstract class" interface. It can implement other interfaces, but won't be able to inherit any other type. This may or may not be a problem, depending on the scenario.

If it makes you feel better about the design, name your pure abstract class following the .NET convention for interfaces. Eg IFoo instead of Foo .

Of course, it does imply the question: why do you want to do this? If you have no implementation at all, what harm could come from allowing other code to implement your interface?

But from a practical point of view, it's possible to enforce your rules the way you want.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM