简体   繁体   English

有没有办法创建一个无法在它的程序集之外实现的公共.NET接口?

[英]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. 为了在.NET中保持二进制向后兼容性,通常无法向公共类和接口添加新的抽象方法。 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. 因为Foo的构造函数是内部的,所以我的程序集之外的任何人都不能扩展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. 因此,我可以向Foo添加新的抽象方法而不用担心向后兼容性,因为我知道另一个程序集中的类不能扩展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 interfaceinternal interface 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 当然,缺点是您需要记住在需要时将其转换为IChildInterface ,而不是简单地将其用作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. 但是因为在IL中,接口本质上只是一个纯粹的抽象类(即没有任何实现的接口),所以你可以使用你已经描述过的技术,它实际上是相同的。

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. 如果它让您对设计感觉更好,请按照接口的.NET约定命名纯抽象类。 Eg IFoo instead of Foo . 例如IFoo而不是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. 但从实际角度来看,可以按照自己的方式执行规则。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么.NET ObservableCollection <T>实现为类而不是接口? - Why is .NET ObservableCollection<T> implemented as a class and not an interface? 继承接口的方法不能明确地声明为“公共” - Inherited Interface's Method Can't Be Explicitly Declare as “Public” 如何在 C# 中创建一个可以被 MATLAB 使用的 .net 程序集? - How to create a .net assembly in C#, which can be consumed by MATLAB? 将实施哪个界面? - Which interface will be implemented? 如何创建一个未实现的接口方法,在VB.Net中显示异常代码,就像在C#中一样 - How to create an interface method which when not implemented shows exception code in VB.Net, just like in C# 谁能解释一下层次树公共接口IGenericRepository<t> 其中T:class?</t> - can any one explain the hierarchy tree public interface IGenericRepository<T> where T: class? 有没有办法检查用于创建.Net项目的IDE - Is there any way to check which IDE was used to create .Net project 为什么我必须为vb.net中的接口实现一个函数,而该函数显然不需要在C#中实现 - Why must I implement a function for an interface in vb.net which apparently doesn't need to be implemented in C# 为什么我的视图模型不能与实现接口的通用ViewModel绑定? (ASP.NET MVC 3) - Why can't my view's model bind with my generic ViewModel which implements an interface? (ASP.NET MVC 3) 在公共 class 之外看不到数组 - Can't see array outside a public class
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM