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

本文关键字:抽象 子类 覆盖 方法 我可以 | 更新日期: 2023-09-27 17:47:23

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

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

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

好吧,

你可以做一些涉及#if的非常混乱的代码 - 即DEBUG它是虚拟的(对于设计师来说),但在RELEASE它是抽象的。不过,维护起来真的很痛苦。

但除此之外:基本上没有。如果你想要设计器支持,它不能是抽象的,所以你只剩下"虚拟"(大概是基方法抛出NotImplementedException)。

当然,你的单元测试将检查方法是否已实现,是吗?;-p

实际上,通过泛型进行测试可能很容易 - 即具有以下形式的通用测试方法:

[Test]
public void TestFoo() {
  ActualTest<Foo>();
}
[Test]
public void TestBar() {
  ActualTest<Bar>();
}
static void ActualTest<T>() 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,并公开允许您更改实现的属性。

请注意,构造函数中未设置"设计模式"。它是在 VS 解析 InitializeComponents() 方法之后设置的。

我知道

它不是你所追求的,但你可以让你在基类中的所有存根抛出 NotImplementException。然后,如果任何子类没有重写它们,则在调用基类中的方法时,将出现运行时异常。

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

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

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

在这种情况下,您希望一个未重写的虚拟方法引发编译时异常(而不是运行时异常)。基本上是一个抽象的方法。

让虚拟方法表现得像抽象方法只会给你创造一个混乱的世界。

另一方面,VS插件设计通常不完全处于同一水平(这有点不公平,但肯定没有语言设计阶段那么严格 - 这是正确的)。一些 VS 工具,如类设计器和当前的 WPF 编辑器,是不错的想法,但还不是真正完整的。

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

某个时候(也许在下一个VS中),他们会整理类设计者如何处理抽象类,然后你会有一个黑客,不知道为什么它是这样编码的。

破解代码以适应设计师应该始终是最后的手段,并且当您尝试将黑客最小化时。我发现通常最好拥有简洁、可读的代码,这些代码可以快速理解,而不是在当前损坏的工具中工作的拜占庭代码。

以ms为例...

Microsoft Silverlight 中的用户控件模板执行此操作。 #if 是完全可以接受的,并且该工具是否会很快解决它是值得怀疑的。 恕我直言