【问题标题】:Auto implement properties in inherited form以继承的形式自动实现属性
【发布时间】:2014-08-19 17:15:49
【问题描述】:

我正在创建一个表单来管理我的应用程序的报告,其想法是每个报告表单都继承自这个基本表单。我的问题是它包含必须分配的几个属性,如果我已经调用了 all,我需要在每个子表单上进行验证,所以......我想知道是否有一种方法可以自动调用所有这些属性.

这是控制器代码的一部分:

public abstract partial class ReportsController()
{
    public string Table{ get; set; }
    public string Fields{ get; set; }
    public string Condition{ get; set; }
    public string Group{ get; set; }
    public string Order{ get; set; }
    public DataGridViewColumnCollection Columns{ get; set; }
    public SortedList<string, string> ComboboxFields{ get; set; }
    etc...

    protected abstract void New();
    protected abstract void Edit();
    protected abstract void Print();
}

如您所见,方法不是问题,它们是抽象的,因此必须声明它们(感谢 Resharper,如果我错过了,我会收到警告)。

子窗体:

public partial class frmReportGuards : ReportsController
{
     public frmReportGuards()
     {
         code...
     }
     protected override void New()
     {
         code...
     }
     other methods...
}

我正在寻找这个:

public partial class frmReportGuards : ReportsController
{
     public frmReportGuards()
     {
         //Auto assigned properties.
         Table = "";
         Fields = "";
         Condition = "";
         Group = "";
         Order = "";
         Columns = new DataGridViewColumnCollection();
         ComboboxFields = new SortedList<string, string>();
     }
     protected override void New()
     {
         code...
     }
     other methods...
}

我不知道我是否在这里毫无意义:/ 我真的需要摆脱这种怀疑,如果可能的话......然后简化我的工作。

【问题讨论】:

  • 为什么不向 ReportsController 添加构造函数并在那里设置属性?
  • 不是关于初始化属性,我想我解释错了,是关于强制子类实现它们。

标签: c# inheritance properties declare


【解决方案1】:

如果您的目标是确保将您的属性初始化为某个默认值,只需将构造函数添加到 ReportsController 并在那里设置属性。

【讨论】:

  • 不,是关于实现子类中的每个属性,就像@ForeverZer0 说的,我可能需要一个接口,但我之前没有考虑过......
  • @a.daw 好的,所以只需将属性声明为抽象。无需创建界面。
  • @a.daw 在单独的接口中定义属性只会引入不必要的复杂性。除非接口提供了对 ReportsController 类的有用抽象,否则请坚持使用抽象属性。
  • 我做到了,但我将第一个回答的内容标记为已接受,但我非常感谢您的帮助 :)
【解决方案2】:

现在我明白了,如果你需要强制实现,你应该使用抽象属性来实现,继承的类应该实现,并且可以使用自动属性来实现:

public abstract class A
{
    public abstract int MyProperty { get; set; }
}

public class B : A
{
    public override int MyProperty { get; set; }
}

【讨论】:

  • 这就是我要找的东西,我很惭愧地说我不知道​​属性可以是抽象的......我打算把我所有的代码都改成一个接口,但是这个以更简单的方式解决它:) 非常感谢。
【解决方案3】:

简短的答案不在 C#5.0 中,在 C#6.0 中你有 Auto-Property initializers,但我认为这不是你想要的。

假设您需要一个无参数构造函数,您可以创建一个从基本构造函数调用的 Init 抽象方法,并检查您的初始化是否遗漏了某个属性。您可以在此处引发异常或显示指示失败的可视消息。

所以在基地你做:

public abstract partial class ReportsController()
{
    public ReportsController()
    {
        InitializeComponent();
        //now your method
        Init();
        CheckProperties();            
    }

    protected virtual void CheckProperties()
    {
       if(Table==null)
          addVisualErrorMessage("Table property missing");
       //and so on
    }

    protected abstract void Init();
}

但也许您必须重新考虑您的设计并提供具有所有属性的单个类,因此您可以创建一个抽象方法,强制您提供所有这些重要属性覆盖单个方法:

public class ComplexProperties
{
  public string Table{ get; set; }
  public string Fields{ get; set; }
  public string Condition{ get; set; }
  public string Group{ get; set; }
  public string Order{ get; set; }
  public DataGridViewColumnCollection Columns{ get; set; }
  public SortedList<string, string> ComboboxFields{ get; set; }
}

public abstract partial class ReportsController()
{
    public ComplexProperties Properties {get; private set;}

    public ReportsController()
    {
        InitializeComponent();
        //now your method
        Properties= Init();
        CheckProperties(); 
    }

    protected abstract ComplexProperties Init();
}

在任何情况下,我都希望有一个带参数的基本构造函数:

public abstract partial class ReportsController()
{
    public ComplexProperties Properties {get; private set;}

    public ReportsController(ComplexProperties properties)
    {
        Properties=properties;
        CheckProperties();
    }
 }

然后从构造函数初始化:

 public partial class MyReport:ReportsController
 {
    public MyReport():base(new ComplexProperties { Table="",...})
    {
    }
 }

【讨论】:

  • 感谢您花时间回答,但我认为我没有很好地解释它......我需要强制子类实现属性,而不是初始化它们,我的目标是确保它们中的每一个都得到实施,所以我不会错过分配一个。
  • 因此,如果您需要强制执行属性,您也可以执行抽象属性,我为此解决方案添加了另一个答案。
【解决方案4】:

您可以为抽象基类和子类都需要实现的属性实现接口。

【讨论】:

  • 嗯,我认为这正是我应该做的......一直以来我一直在考虑如何通过继承来实现属性,但接口实际上可以解决这个问题......谢谢,我会的试试看,如果它有效,将标记为答案:)
猜你喜欢
  • 2015-10-03
  • 2010-09-29
  • 1970-01-01
  • 1970-01-01
  • 2014-08-25
  • 2012-12-17
  • 2019-10-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多