我正在创建一个表单来管理我的应用程序的报告,我们的想法是每个报表都继承自这个基本表单。我的问题是它包含了几个必须分配的属性,如果我已经调用了所有,我需要在每个子表单上进行验证,所以...我想知道是否有办法自动调用所有那些属性。
这是控制器代码的一部分:
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...
}
我不知道我在这里是否感到茫然:/我真的需要摆脱这种怀疑,如果可能的话......那么就简化我的工作。
答案 0 :(得分:2)
如果您的目标是确保将属性初始化为某个默认值,只需将构造函数添加到ReportsController
并在那里设置属性。
答案 1 :(得分:1)
简短回答不在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="",...})
{
}
}
答案 2 :(得分:0)
您可以为抽象基类和子类需要实现的属性实现接口。
答案 3 :(得分:0)
现在我明白了,如果你需要强制实现,你应该用抽象属性来实现,然后继承类应该实现,并且可以用自动属性实现:
public abstract class A
{
public abstract int MyProperty { get; set; }
}
public class B : A
{
public override int MyProperty { get; set; }
}