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

C# 我可以强制子类重写方法而不使其抽象吗?,c#,.net,visual-studio-2008,abstract-class,C#,.net,Visual Studio 2008,Abstract Class,我有一个带有一些抽象方法的类,但我希望能够在设计器中编辑该类的子类。但是,设计器不能编辑子类,除非它可以创建父类的实例。所以我的计划是用存根替换抽象方法,并将它们标记为虚拟的-但是如果我创建另一个子类,如果我忘记实现它们,我就不会得到编译时错误 有没有一种方法可以标记这些方法,以便它们必须由子类实现,而不将它们标记为抽象的?好吧,你可以编写一些涉及#if-的非常混乱的代码,即在调试中,它是虚拟的(对于设计者而言),但在发布版中,它是抽象的。不过,要维持下去真的很痛苦 但除此之外:基本上没有。如果

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


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

好吧,你可以编写一些涉及
#if
-的非常混乱的代码,即在
调试
中,它是虚拟的(对于设计者而言),但在
发布版中,它是抽象的。不过,要维持下去真的很痛苦

但除此之外:基本上没有。如果您想要设计器支持,它不能是抽象的,因此您只能使用“virtual”(可能是基本方法抛出了一个
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
}
[测试]
公共void TestFoo(){
实际测试();
}
[测试]
公共void TestBar(){
实际测试();
}
静态void ActualTest(),其中T:SomeBaseClass,new(){
T obj=新的T();
涉及obj的东西
}

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

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

您可以在类中使用“引用实现”习惯用法

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插件设计通常不在同一水平(这有点不公平,但肯定比语言设计阶段应用的严谨性要低——这是正确的)。一些VS工具,如类设计器和当前的WPF编辑器,是不错的想法,但还没有真正完成

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

在某个时候(可能在下一个VS中),他们会整理类设计器如何处理抽象类,然后你会有一个不知道它为什么以这种方式编码的黑客


它应该始终是黑客攻击代码以适应设计者的最后手段,并且当您尝试将黑客攻击最小化时。我发现,通常最好是使用简洁易读的代码,而不是在当前已损坏的工具中使用的拜占庭代码。请注意,构造函数中没有设置“DesignMode”。它是在VS解析InitializeComponents()方法后设置的。

以ms为例


Microsoft使用silverlight中的用户控件模板来实现这一点#如果是完全可以接受的,并且怀疑工具是否会在短期内工作。IMHO

这在VisualStudio中一直是一个缺陷,但您不能为了多年来该工具所缺乏的东西而牺牲可读性和可维护性。您是否曾尝试通过编程方式修改复杂的WinForms?这需要更长的时间,也是很多挫折的根源。微软包括这个设计师是有原因的,我认为做一些“黑客”来提高项目的可维护性是完全合法的。一定要记录下你在做什么以及为什么要这么做。@Tim-我并不是说这是不合法的,我的观点是,这应该是破解代码以适应工具的最后手段。在这种情况下,我认为最好的解决方案实际上是在接受的答案中,在虚拟成员中抛出
NotImplementedException
,并对代码进行单元测试。您是如何在设计器中设计基类的?