我可能会走错方向,所以让我试着理清我的想法(并希望从你们那里得到一些提示):
想象一下枚举:
public enum ReportType
{
Performance,
Trending,
Statistical
}
此枚举也将是表单构造函数的属性或参数。 ReportType的值将决定如下内容:
a) the text displayed at the top of the form
b) Which controls are visible
c) the text for a combobox <---!!!! this is where the 2nd enum comes in
关于第二个枚举,如果它是一个Performance ReportType,我想要:
public enum PerformanceGraph
{
Bar,
Line,
Pie,
Area
}
如果是趋势,我希望:
public enum TrendingGraph
{
Bar,
Line
}
此表单只是收集用户输入。我的意思是,我宁愿不为一个简单的形式进入一些复杂的继承结构。当我能够快速做出类似的事情时,似乎需要付出很多努力(我可能是错的):
(想象一下这个构造函数)
public ReportInputForm(ReportType RptType)
{
m_RptType = RptType;
if (RptType == ReportType.Performance)
{
this.Text = "Performance Title";
this.CheckBoxCtl.Visible = false;
this.GraphCombo.Items.AddRange(Enum.GetNames(typeof(PerformanceGraph)));
this.GraphCombo.SelectedIndex = (int)PerformanceGraph.Bar;
}
else if (RptType == ReportType.Trending)
{
// blah, blah
}
else if (RptType == ReportType.Statistical)
{
// blah, blah
}
else
{
throw new ArgumentException("Invalid ReportType enum value");
}
}
当您想要使用GraphCombo实际执行某些操作时,它开始变得毛茸茸,因为现在您需要知道它是用于投射的ReportType。
另外,回到我的构造函数,假设我想向它发送一个Graph Value,这样我们就可以设置GraphCombo的SelectedIndex(这可能是用户上次选择的值,而不是设置某种类型的默认值)。嗯....
public ReportInputForm(ReportType RptType, ???WhichGraphEnum???)
{
}
我的意思是,现在有三个图形枚举,因为有三个ReportType。另外,想象一下,再添加几个ReportType。
我想我可以使用int / long:
public ReportInputForm(ReportType RptType, int lastGraphType)
{
}
但我想我正在努力成为Enum先生,我的编译时检查。换句话说,如果我可以使用某种类型的枚举(如此),我可以检测到错误:
ReportInputForm foo = new ReportInputForm(ReportType.Trending, GraphType.Area);
相反:
// Is 4 even a valid graph type for the trending report? Answer: No
ReportInputForm foo = new ReportInputForm(ReportType.Trending, 4);
我已经絮絮叨叨了。也许这更像是一个设计问题而不是枚举相关。我只想找到一些关于如何解决这个问题的想法。谢谢!
################################################## ################################ ################################################## ################################ 编辑开始于此################## ################# ################################################## ################################ ################################################## ################################这是对使用Generics的回应(如果我有点慢,我道歉;感谢Daniel对你的回复):
这是一个建议:
ReportInputForm<TrendingReport> = new ReportInputForm<TrendingReport>(GraphType.Area);
好的,所以如果我要使用Generics(和Form),我必须创建一个Type。我想象的是这样的事情(我们现在只公开一个函数,设置标题):
public abstract class ReportType
{
public abstract string GetTitle();
}
public class PerformanceReport : ReportType
{
public PerformanceReport()
{
}
public override string GetTitle()
{
return "This is my Performance title";
}
}
public class TrendingReport : ReportType
{
public TrendingReport()
{
}
public override string GetTitle()
{
return "This is my Trending title";
}
}
public partial class Form1<T> : Form
where T : ReportType, new()
{
T foo = null;
public Form1()
{
InitializeComponent();
foo = new T();
this.Text = foo.GetTitle();
}
}
所以,现在我可以做一些像建议的那样:
Form1<TrendingReport> f = new Form1<TrendingReport>();
这很酷,而且它有效(我的标题取决于类型),但我不认为这有助于我原来的问题。第二个枚举。
如果我使用的是PerformanceReport,我希望我的GraphType枚举为:
public enum PerformanceGraph
{
Bar,
Line,
Pie,
Area
}
如果我使用的是TrendingReport,我希望我的GraphType枚举为:
public enum TrendingGraph
{
Bar,
Line
}
换句话说,这个枚举取决于班级(或者我原来的问题,取决于第一个词汇)。
我的意思是,我想我可以在抽象类中放入一个包含所有图形类型的枚举:
public abstract class ReportType
{
public enum GraphType
{
Bar,
Line,
Pie,
Area
}
public abstract string GetTitle();
}
但是,这违背了我原来问题的目的。因为这现在变得合法(想象我修改了Form1的构造函数):
Form1<TrendingReport> f = new Form1<TrendingReport>(ReportType.GraphType.Pie);
请记住,TrendingReport应该只有Bar和Line。我正在尝试编译时检查这个。我肯定也会遗漏一些东西(关于泛型)。
答案 0 :(得分:7)
如果表单的类型取决于枚举的值,我会将枚举变为类型本身。然后使表单类通用。
例如:
ReportInputForm<TrendingReport> = new ReportInputForm<TrendingReport>(GraphType.Area);
甚至:
ReportInputForm<AreaGraph> = new TrendingReportForm<AreaGraph>();
假设TrendingReportForm
是ReportInputForm
的子类。
如果您的某个行的行为基于某个枚举值而发生更改,您应该寻找机会将更改行为重构为可以委派给子类的单独方法。
答案 1 :(得分:1)
这听起来像是一个非常合理的地方,可以使用继承,基类ReportInputForm
和子类PerformanceReportInputForm
,TrendingReportInputForm
和StatisticalReportInputForm
。它看起来并不特别复杂,它可以在保持编译时类型检查的同时巧妙地避免任何switch / case语句或long。或者,您可以根据策略模式实现它,这会增加一些脚手架和开销,但允许您动态更改报告类型。
答案 2 :(得分:0)
通用表格?
ReportInputForm<T>