在继承形式中自动实现属性
本文关键字:实现 属性 继承 | 更新日期: 2023-09-27 18:18:53
我正在创建一个表单来管理我的应用程序的报表,其想法是每个报表表单都继承自这个基本表单。我的问题是,它包含几个必须分配的属性,我需要在每个子窗体上验证,如果我已经调用了所有,所以……我想知道是否有一种方法可以自动调用所有这些属性。
控制器代码的一部分:
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
添加一个构造函数并在那里设置属性。
现在我明白了,如果你需要强制实现,你应该用抽象属性来实现,继承类应该实现,并且可以用auto-properties来实现:
public abstract class A
{
public abstract int MyProperty { get; set; }
}
public class B : A
{
public override int MyProperty { get; set; }
}
简短的回答不是在c# 5.0中,在c# 6.0中你有Auto-Property初始化器,但我认为这不是你要找的。
假设你需要一个无参数的构造函数,你可以创建一个从基构造函数调用的Init抽象方法,并检查你的初始化是否遗漏了一个属性。在这里,您可以抛出异常或显示显示失败的可视消息。
那么在base中你可以这样写:
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="",...})
{
}
}
您可以为抽象基类和子类都需要实现的属性实现一个接口。