我可以强制子类覆盖方法而不使其抽象化吗?

我有一个带有一些抽象方法的类,但我希望能够在设计器中编辑该类的子类。 但是,设计者无法编辑子类,除非它可以创建父类的实例。 所以我的计划是用存根替换抽象方法并将它们标记为虚拟 – 但是如果我创建另一个子类,如果我忘记实现它们,我将不会得到编译时错误。

有没有办法标记方法,以便它们必须由子类实现,而不将它们标记为抽象?

那么你可以做一些涉及#if非常混乱的代码 – 即在DEBUG它是虚拟的(对于设计者而言),但在RELEASE它是抽象的。 但是,维持真正的痛苦。

但除此之外:基本上,没有。 如果你想要设计师的支持它不能是抽象的,所以你留下了“虚拟”(大概是使用基本方法抛出一个NotImplementedException )。

当然,你的unit testing会检查方法是否已经实现,是吗? ;-p

实际上,通过generics测试可能很容易 – 即具有表格的通用测试方法:

 [Test] public void TestFoo() { ActualTest(); } [Test] public void TestBar() { ActualTest(); } static void ActualTest() where T : SomeBaseClass, new() { T obj = new T(); Assert.blah something involving obj } 

您可以在类中使用对实现习语的引用。

 public class DesignerHappy { private ADesignerHappyImp imp_; public int MyMethod() { return imp_.MyMethod() } public int MyProperty { get { return imp_.MyProperty; } set { imp_.MyProperty = value; } } } public abstract class ADesignerHappyImp { public abstract int MyMethod(); public int MyProperty {get; set;} } 

DesignerHappy只显示您想要的接口,但将所有调用转发给实现对象。 您可以通过对ADesignerHappyImp进行子类化来扩展行为,这会强制您实现所有抽象成员。

您可以提供ADesignerHappyImp的默认实现,默认情况下用于初始化DesignerHappy并公开允许您更改实现的属性。

请注意,“DesignMode”未在构造函数中设置。 在VS解析InitializeComponents()方法之后设置它。

我知道它不是你想要的,但是你可以让基类中的所有存根都抛出NotImplementedException。 然后,如果您的任何子类没有覆盖它们,那么当调用基类中的方法时,您将获得运行时exception。

Component类包含一个名为“DesignMode”的布尔属性,当您希望代码在设计器中的行为与运行时不同时非常方便。 在这种情况下可能会有一些用处。

作为一般规则,如果语言中没有办法做某事通常意味着有一个很好的概念理由不这样做。

有时这将是语言设计者的错 – 但不经常。 通常我发现他们比我更了解语言设计;-)

在这种情况下,您需要一个未被重写的虚方法来抛出编译时exception(而不是运行时一个exception)。 那么基本上是一种抽象方法。

使虚拟方法像抽象方法一样,只会为你创造一个混乱的世界。

另一方面,VS插件设计通常不是完全相同的水平(这有点不公平,但肯定不如语言设计阶段那么严格 – 而且正确如此)。 一些VS工具,比如类设计师和当前的WPF编辑器,都是很好的想法,但还不是很完整。

在您描述的情况下,我认为您有一个不使用类设计器的论点,而不是破解代码的参数。

在某些时候(可能在下一个VS中),他们会整理class级设计师处理抽象类的方式,然后你就会知道为什么它会以这种方式编码。

它应该永远是破解你的代码以适应设计师的最后手段,并且当你试图保持最小的黑客时。 我发现通常更好的是拥有简洁易读的代码,这些代码可以在当前破坏的工具中运行的拜占庭代码中快速理解。

以ms为例……

Microsoft使用silverlight中的用户控件模板执行此操作。 #if是完全可以接受的,并且工具很快就可以解决它。 恕我直言