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

发布于 2024-07-08 03:13:23 字数 182 浏览 6 评论 0原文

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

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

I have a class with some abstract methods, but I want to be able to edit a subclass of that class in the designer. However, the designer can't edit the subclass unless it can create an instance of the parent class. So my plan is to replace the abstract methods with stubs and mark them as virtual - but then if I make another subclass, I won't get a compile-time error if I forget to implement them.

Is there a way to mark the methods so that they have to be implemented by subclasses, without marking them as abstract?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

围归者 2024-07-15 03:13: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
}

Well you could do some really messy code involving #if - i.e. in DEBUG it is virtual (for the designer), but in RELEASE it is abstract. A real pain to maintain, though.

But other than that: basically, no. If you want designer support it can't be abstract, so you are left with "virtual" (presumably with the base method throwing a NotImplementedException).

Of course, your unit tests will check that the methods have been implemented, yes? ;-p

Actually, it would probably be quite easy to test via generics - i.e. have a generic test method of the form:

[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
}
坐在坟头思考人生 2024-07-15 03:13:23

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

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 并公开允许您更改实现的属性。

You could use the reference to implementation idiom in your class.

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 just exposes the interface you want but forwards all the calls to the implementation object. You extend the behavior by sub-classing ADesignerHappyImp, which forces you to implement all the abstract members.

You can provide a default implementation of ADesignerHappyImp, which is used to initialize DesignerHappy by default and expose a property that allows you to change the implementation.

白色秋天 2024-07-15 03:13:23

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

Note that "DesignMode" is not set in the constructor. It's set after VS parses the InitializeComponents() method.

记忆里有你的影子 2024-07-15 03:13:23

我知道这并不完全是您想要的,但您可以使基类中的所有存根抛出 NotImplementedException。 然后,如果您的任何子类没有重写它们,那么当调用基类中的方法时,您将收到运行时异常。

I know its not quite what you are after but you could make all of your stubs in the base class throw the NotImplementedException. Then if any of your subclasses have not overridden them you would get a runtime exception when the method in the base class gets called.

无名指的心愿 2024-07-15 03:13:23

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

The Component class contains a boolean property called "DesignMode" which is very handy when you want your code to behave differently in the designer than at runtime. May be of some use in this case.

岁月打碎记忆 2024-07-15 03:13:23

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

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

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

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

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

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

在某些时候(也许在下一个 VS 中)他们会整理类设计器处理抽象类的方式,然后你就会遇到一个 hack,不知道为什么要这样编码。

它应该始终是修改代码以适应设计者的最后手段,并且当您确实尝试将修改保持在最低限度时。 我发现,与在当前损坏的工具中工作的拜占庭代码相比,拥有简洁、可读且能够快速理解的代码通常更好。

As a general rule, if there's no way in a language to do something that generally means that there's a good conceptual reason not to do it.

Sometimes this will be the fault of the language designers - but not often. Usually I find they know more about language design than I do ;-)

In this case you want a un-overridden virtual method to throw a compile time exception (rather and a run time one). Basically an abstract method then.

Making virtual methods behave like abstract ones is just going to create a world of confusion for you further down the line.

On the other hand, VS plug in design is often not quite at the same level (that's a little unfair, but certainly less rigour is applied than is at the language design stage - and rightly so). Some VS tools, like the class designer and current WPF editors, are nice ideas but not really complete - yet.

In the case that you're describing I think you have an argument not to use the class designer, not an argument to hack your code.

At some point (maybe in the next VS) they'll tidy up how the class designer deals with abstract classes, and then you'll have a hack with no idea why it was coded that way.

It should always be the last resort to hack your code to fit the designer, and when you do try to keep hacks minimal. I find that it's usually better to have concise, readable code that makes sense quickly over Byzantine code that works in the current broken tools.

蝶舞 2024-07-15 03:13:23

以 ms 为例...

Microsoft 使用 silverlight 中的用户控件模板来实现此目的。 #if 是完全可以接受的,但令人怀疑的是该工具能否很快解决它。 恕我直言

To use ms as an example...

Microsoft does this with the user control templates in silverlight. #if is perfectly acceptable and it is doubtful the the tooling will work around it anytime soon. IMHO

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文