首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用类(而不是接口)设置插件机制是否不正确?

使用类(而不是接口)设置插件机制是否不正确?
EN

Stack Overflow用户
提问于 2016-12-17 11:14:15
回答 2查看 89关注 0票数 2

假设这个假设的情况:我有一个类的层次结构:

代码语言:javascript
复制
public class MyBase : System.Windows.Forms.TreeNode 
{ 
    public virtual void Init() {...} 
}

现在,我希望允许第三方使用MyBase开发它们的派生类,如下所示:

代码语言:javascript
复制
public class Drv1 : MyBase { public override void Init() {...} }
public class Drv2 : MyBase { public override void Init() {...} }

我希望我的应用程序能够使用Drv1和Drv2作为插件。

现在,我的问题是:

  1. 使用类(而不是接口)来设置插件机制是不正确的(或者是错误的做法)吗?
  2. 我是否犯了错误,我没有使用接口为第三方提供接口?(因为我想说服别人为我的应用程序开发插件)
  3. 如果问题2的回答是肯定的,我如何使用接口(因为MyBase是从TreeNode派生的)?(这个答案对我来说至关重要)

在此之前,非常感谢您。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-12-17 15:00:39

使用类(而不是接口)来设置插件机制是不正确的(或者是错误的做法)吗?

C#或.NET都没有将其标记为不正确的任何内容。它们描述了在什么情况下您的代码将继续工作,什么时候不能工作。糟糕的实践是一个意见问题,但这两种方法都有其优点和缺点。

如果问题2的回答是肯定的,我如何使用接口(因为MyBase是从TreeNode派生的)?(这个答案对我来说至关重要)

如果调用方需要提供从TreeNode派生的类型,并且希望使用接口,则可以。

代码语言:javascript
复制
public interface IMyInterface {
    void Init() {...}
}

您不能要求实现IMyInterface的类从TreeNode派生,但不需要:您可以确保向您自己的应用程序公开的唯一方法是通过泛型注册方法,其中泛型类型约束确实强制类型从TreeNode派生并实现此接口:

代码语言:javascript
复制
public void RegisterTreeNode<T>() where T : TreeNode, IMyInterface {...}

如果插件能够调用RegisterTreeNode<Drv1>(),那么在编译时就可以保证它将符合您的要求。当然,您可以使用不同的方法签名,可能是处理TreeNode类的各个实例的方法签名,这里的关键是类型约束。如果打电话的人

代码语言:javascript
复制
class X : IMyInterface { public void Init() {...} }

然后

代码语言:javascript
复制
RegisterTreeNode<X>();

编译器将简单地拒绝这一点。插件可能会创建这个X本身的实例,但是如果您的应用程序从未看到它们,它们不会造成任何伤害。

然后第三方可以这样做:

代码语言:javascript
复制
public class Drv1 : TreeNode, IMyInterface { ... }
public class Drv2 : TreeNode, IMyInterface { ... }

甚至是

代码语言:javascript
复制
public class Drv3 : SuperTreeNode, IMyInterface { ... }

其中SuperTreeNode是从标准TreeNode派生的。

这可能是在这里使用接口的主要好处:它与在标准TreeNode之上提供额外功能的现有类兼容。

这是双向的:在这里使用公共基类(而不是接口)的主要好处是您自己的代码可以提供额外的功能。

P.S.:根据您所追求的目标,也可能将其解耦,使您的基类/接口负责创建TreeNode对象,而不是从TreeNode派生。支持这种方法的一般规则称为“组合而不是继承”,值得一读。它可能适合或可能不适合您的特定用例。

票数 1
EN

Stack Overflow用户

发布于 2016-12-17 14:27:52

我使用以下规则:

如果基础中需要任何代码,那么就选择class

如果您只需要结构或者需要“继承”多个class,请使用interfaces

如果两者都需要,特性和多重继承都会使用。

这真的取决于你以后对那个类做什么。

在您的情况下,您应该使用基本的class,因为virtual方法中有一些代码,并且您继承的类是您的第三方。

但是,一旦您的业务类应该使用该类的不同实现,那么添加接口并在IoC或其他方面使用它的价值。

我认为仅仅为了它而使用接口是不正确的。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41197977

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档