c#泛型和反射的设计应用(一)

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

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

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

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

//定义设备状态  
   public enum OperateState { Run, Pause, Stop };  
   //设备状态转换规则类  
   public class OperateStateRule<T> 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);  
           }  
       }  
   } 


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/yutao051/archive/2010/02/04/5289025.aspx

调用示例:

     view plaincopy to clipboardprint?
ToolStripButton btnStart;  
ToolStripButton btnPause;  
ToolStripButton btnStop;  
//生成对象时绑定相应的按钮  
OperateStateRule<ToolStripButton> rule = new  OperateStateRule<ToolStripButton>(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<ToolStripButton> rule = new  OperateStateRule<ToolStripButton>(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<T>  
    {  
        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<T>
    {
        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属性即可。

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/yutao051/archive/2010/02/04/5289025.aspx

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值