繁体   English   中英

C#表继承Abstract类并实现接口。

[英]C# Form that inherit Abstract class AND implements interface.

我需要在我的项目中有多个Form类。 因此,考虑将这些形式的所有内容放在一起,在抽象课程中。 该类将具有继承Form类和接口。 那样的:

public interface IMyForm
{
void Init();
}

public abstract class AMyForm : Form, IMyForm
{
    void IBrowser.Init()
    {
        throw new NotImplementedException();
    }     
}

public partial class MainClass : AMyForm 
{

// But here the warning is shown (That i have to add override keyword),
// but when i do, The error is shown that i cannot override from non abstract thing 
    public void Init() 
    {
    }
}

你能告诉我怎么做到的吗?

虽然Jon Skeets的答案对于一般编程是正确的,但我建议AGAINST使用表单和用户控件上的抽象类。 第一个问题是,该设计器将无法创建抽象类的实例,因此无法在设计器中显示继承FROM抽象形式的表单。 这意味着您将无法通过设计器向表单添加新控件, 除非 - 如下面的注释中所示 - 添加实现抽象类的代理类,然后将其用作其他继承表单的基础,例如: AbstractMyForm -> MyFormSurrogate -> MyForm

在我看来,第二个也是更大的问题,这意味着你试图将逻辑粘贴到表格中。 通常是不希望的,特别是如果您最终将业务逻辑耦合到您的显示技术,在这种情况下是Winforms 我的建议是尝试使用Model View Presenter模式在普通类中使用尽可能多的逻辑(使用抽象类,接口等),然后将数据绑定到表单。 如果存在共享的可视部分(例如:一组复选框),请对这些部分进行用户控制,并在表单上重复使用它们。

我希望我没有过多地介绍你使用winforms的知识,但是当我开始进入GUI开发时我遇到了类似的问题。

您只是想在抽象类中使用显式接口实现:

public abstract class AMyForm : Form, IMyForm
{
    public virtual void Init()
    {
        throw new NotImplementedException();
    }     
}

或者只是把它抽象化:

public abstract class AMyForm : Form, IMyForm
{
    public abstract void Init();
}

在这两种情况下,您只需在具体类中覆盖它。

或者,如果您真的想在抽象类中使用显式接口实现,则应该在具体类中再次使用它:

public partial class MainClass : AMyForm, IMyForm
{
    void IMyForm.Init() 
    {
        // Stuff
    }
}

缺点是AMyForm任何子类都没有这样做,基本上会有破坏的IMyForm实现。 使用第一种方法在这里更好。

编辑:或者,根据supercat的建议:

public abstract class AMyForm : Form, IMyForm
{
    void IBrowser.Init()
    {
        InitImpl();
        // And anything else you need...
    }     

    // Or abstract...
    protected virtual void InitImpl()
    {
    }
}

然后在具体类中重写InitImpl

抽象类没有在设计视图中显示; 你可以通过向抽象类添加编译器if语句来使它在设计时不抽象。

#if RELEASE
    public abstract class AbstractForm : Form, IInterface
#else
    public class AbstractForm : Form, IInterface
#endif
    {
        // Your abstract code here.
    }

这是一个非常有效的小黑客。 您可以使用相同的技巧在设计时和运行时之间切换虚方法和抽象方法。

附录:

应该注意,不需要使用抽象形式。 从非抽象表单继承它会更有效并且创建更少的潜在问题。

public partial class Screen : Form, IInterface
{
    // Base Class here, complete with .designer.cs and .resx
    public Screen()
    {
        InitialiseComponent();
    }

    #region IInterface imported methods
    public partial void SomeMethod()
    {
        // Do something.
    }
    #endregion
}

然后,如果您想创建一个登录屏幕,例如:

public partial class LogonScreen : Screen, IInterface
{
    // Derived Class here, complete with .designer.cs and .resx
    public Screen()
    {
        InitialiseComponent();
    }

    #region IInterface imported methods
    public partial void SomeMethod()
    {
        // Do more somethings!
    }
    #endregion
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM