C# 泛型设计应用示例

原创|其它|编辑:郝浩|2010-02-09 10:19:59.000|阅读 726 次

概述:在设备操作面板的设计中总会有一类固定的按钮和操作惯例,但如果每做一个项目都写一套同样的代码实在很没效率的事。

# 界面/图表报表/文档/IDE等千款热门软控件火热销售中 >>

  在设备操作面板的设计中总会有一类固定的按钮和操作惯例,但如果每做一个项目都写一套同样的代码实在很没效率的事。

  设备的操作按钮大多数都会包含启动、暂停、停止这三个按钮,软件界面中也同样需要这三类按钮,软件需要根据设备的状态

  来禁用或启用不同的按钮组合。比如刚启动软件时,启动按钮开启,暂停和停止按钮禁用等等。

  一般设计情况下是用Button,也有的设计会用ToolStripButton,为了使其兼容更多的控件,所以采用了泛型。代码如下:


 view plaincopy to clipboardprint?
  //定义设备状态
  public enum OperateState { Run, Pause, Stop };
  //设备状态转换规则类
  public class OperateStateRule where T : ToolStripItem
  {
  private T start;
  private T pause;
  private T stop;
  private OperateState state = OperateState.Stop;
  private OperateState State
  {
  get { return state; }
  //set { state = value; }
  }
  //绑定控件
  public OperateStateRule(T _start, T _pause, T _stop)
  {
  start = _start;
  pause = _pause;
  stop = _stop;
  Update(OperateState.Stop);
  }
  //根据设备状态更新控件属性
  public void Update(OperateState _state)
  {
  state = _state;
  try
  {
  switch (state)
  {
  case OperateState.Stop:
  start.Enabled = true;
  pause.Enabled = false;
  stop.Enabled = false;
  break;
  case OperateState.Run:
  start.Enabled = false;
  pause.Enabled = true;
  stop.Enabled = true;
  break;
  case OperateState.Pause:
  start.Enabled = true;
  pause.Enabled = false;
  stop.Enabled = true);
  break;
  }
  }
  catch (Exception ex)
  {
  MessageBox.Show(ex.Message);
  }
  }
  }
  //定义设备状态
  public enum OperateState { Run, Pause, Stop };
  //设备状态转换规则类
  public class OperateStateRule where T : ToolStripItem
  {
  private T start;
  private T pause;
  private T stop;
  private OperateState state = OperateState.Stop;
  private OperateState State
  {
  get { return state; }
  //set { state = value; }
  }
  //绑定控件
  public OperateStateRule(T _start, T _pause, T _stop)
  {
  start = _start;
  pause = _pause;
  stop = _stop;
  Update(OperateState.Stop);
  }
  //根据设备状态更新控件属性
  public void Update(OperateState _state)
  {
  state = _state;
  try
  {
  switch (state)
  {
  case OperateState.Stop:
  start.Enabled = true;
  pause.Enabled = false;
  stop.Enabled = false;
  break;
  case OperateState.Run:
  start.Enabled = false;
  pause.Enabled = true;
  stop.Enabled = true;
  break;
  case OperateState.Pause:
  start.Enabled = true;
  pause.Enabled = false;
  stop.Enabled = true);
  break;
  }
  }
  catch (Exception ex)
  {
  MessageBox.Show(ex.Message);
  }
  }
  }

  调用示例:


 view plaincopy to clipboardprint?
  ToolStripButton btnStart;
  ToolStripButton btnPause;
  ToolStripButton btnStop;
  //生成对象时绑定相应的按钮
  OperateStateRule rule = new OperateStateRule(btnStart,btnPause,btnStop);
  //在Click事件里更新状态
  private void btnStart_Click(object sender, EventArgs e)
  {
  rule.Update(OperateState.Run);
  }
  private void btnPause_Click(object sender, EventArgs e)
  {
  rule.Update(OperateState.Pause);
  }
  private void btnStop_Click(object sender, EventArgs e)
  {
  rule.Update(OperateState.Stop);
  }
  ToolStripButton btnStart;
  ToolStripButton btnPause;
  ToolStripButton btnStop;
  //生成对象时绑定相应的按钮
  OperateStateRule rule = new OperateStateRule(btnStart,btnPause,btnStop);
  //在Click事件里更新状态
  private void btnStart_Click(object sender, EventArgs e)
  {
  rule.Update(OperateState.Run);
  }
  private void btnPause_Click(object sender, EventArgs e)
  {
  rule.Update(OperateState.Pause);
  }
  private void btnStop_Click(object sender, EventArgs e)
  {
  rule.Update(OperateState.Stop);
  }

  在类声明上有个where T : ToolStripItem语句,这个是c#类型约束,如果不加这个约束,编译器会报错找不到Enabled属性,

  但有个问题Button和ToolStripButton这两个类不是同一个基类派生,所以无法兼容使用这2个类,因为必须要有这个约束,使得c++

  的一些泛型做法受到限制。

  那还有没有更好的方法来达到理想的效果呢,答案是有的,就是反射。看下面改进的代码例子:


 view plaincopy to clipboardprint?
  //枚举设备状态
  public enum OperateState { Run, Pause, Stop };
  //设备状态转换规则类
  public class OperateStateRule
  {
  private T start;
  private T pause;
  private T stop;
  private OperateState state = OperateState.Stop;
  private OperateState State
  {
  get { return state; }
  //set { state = value; }
  }
  //绑定控件
  public OperateStateRule(T _start, T _pause, T _stop)
  {
  start = _start;
  pause = _pause;
  stop = _stop;
  Update(OperateState.Stop);
  }
  //通过反射设置属性值
  private void SetEnabled(T obj, bool value)
  {
  obj.GetType().InvokeMember("Enabled", BindingFlags.SetProperty, null, obj, new object[] { value});
  }
  //根据设备状态更新控件属性
  public void Update(OperateState _state)
  {
  state = _state;
  try
  {
  switch (state)
  {
  case OperateState.Stop:
  SetEnabled(start, true);
  SetEnabled(pause, false);
  SetEnabled(stop, false);
  break;
  case OperateState.Run:
  SetEnabled(start, false);
  SetEnabled(pause, true);
  SetEnabled(stop, true);
  break;
  case OperateState.Pause:
  SetEnabled(start, true);
  SetEnabled(pause, false);
  SetEnabled(stop, true);
  break;
  }
  }
  catch (Exception ex)
  {
  MessageBox.Show(ex.Message);
  }
  }
  }
  //枚举设备状态
  public enum OperateState { Run, Pause, Stop };
  //设备状态转换规则类
  public class OperateStateRule
  {
  private T start;
  private T pause;
  private T stop;
  private OperateState state = OperateState.Stop;
  private OperateState State
  {
  get { return state; }
  //set { state = value; }
  }
  //绑定控件
  public OperateStateRule(T _start, T _pause, T _stop)
  {
  start = _start;
  pause = _pause;
  stop = _stop;
  Update(OperateState.Stop);
  }
  //通过反射设置属性值
  private void SetEnabled(T obj, bool value)
  {
  obj.GetType().InvokeMember("Enabled", BindingFlags.SetProperty, null, obj, new object[] { value});
  }
  //根据设备状态更新控件属性
  public void Update(OperateState _state)
  {
  state = _state;
  try
  {
  switch (state)
  {
  case OperateState.Stop:
  SetEnabled(start, true);
  SetEnabled(pause, false);
  SetEnabled(stop, false);
  break;
  case OperateState.Run:
  SetEnabled(start, false);
  SetEnabled(pause, true);
  SetEnabled(stop, true);
  break;
  case OperateState.Pause:
  SetEnabled(start, true);
  SetEnabled(pause, false);
  SetEnabled(stop, true);
  break;
  }
  }
  catch (Exception ex)
  {
  MessageBox.Show(ex.Message);
  }
  }
  }

  可以看到已经不需要where子句来约束类型,通过借助泛型和反射实现了更好通用性,不但能使用Button和ToolStripButton,

  还能使用其他的控件,只要有Enabled属性即可。


标签:

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@evget.com

文章转载自:网络转载

为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP