如何在C#中的委托实现

时间:2022-08-30 18:13:09

先说下我为什么会用委托。在最开始想用委托的时候,其实我是拒绝的。为什么?因为结构看起来会有点乱啊,只是写个方法名,然后在括号写几个参数,但是实现却不在当前的对象中,给别人看的时候很不容易找诶。并且你一个委托摆在这,谁知道你的实现是干嘛的,并且对于习惯了封装的编写方式之后,这个方式用的很不习惯。那么问题来了,我怎么会还要用呢。因为我要向界面写一些显示数据,但是那个控件对象在其它类中访问不到啊。c#不像C++,定义一个全局对象很容易,也不想安卓的界面编写有个很好用的消息机制可以刷新界面。所以没办法我只能采用委托了,具体实现的方法只能放在界面对象。

        委托的类型我接触了两种:

1、很常见的delegate;

2、也很常见action<T>,T表示一种数据类型,也就是说这种定义委托的方式,只能有一个参数。

       定义好委托, 接下来就要定义事件了。如下所示:(比如这个委托在class showInfo这个对象中)

   public delegate void  showSomething(string message,int Type);
        public event
showSomething show;

   

      这样一个委托就定义好了。

      这个时候就要有调用和实现了,实现简单,比如在一个窗体的继承类中定义如下:

      class myFrom:Froms

      {

showInfo myInfo;

myFrom()

{

myInfo.show += showSomething;

}

public void showSomething(string,int Type)

{

//do something;

}

      }


    这样就把实现和事件绑定在一起了,不过在showInfo对象中对show进行调用时,最好先判断一下if(show == null)只是为了规范。

   你以为这样就完了吗??其实是没有的。写过安卓开发的人都知道,在刷新界面是不能再子线程中实现的,最好的方式是通过消息机制去实现。如果你不知道安卓的消息机制,我只能说这不是重点,重点是C#界面的控件访问也很坑爹。

        如果你在上面的实现中直接访问了C#的界面控件,这个时候很可能会报错:线程间操作无效: 从不是创建控件的XX的线程访问它。

       坑吧,我被坑哭了。这错误不莫名其妙嘛?我在窗口类中调用的窗口中的控件,你却告诉我的线程不对。仔细想想还真不对,这是C#为了保证线程访问安全的一种保护机制,所以我才对委托很不爽啊。可是要解决这个问题,我不得不又用了一把心酸类----委托,是的又是委托。

      网上提示了三种委托方式,第一种很简单,就是把控件线程安全访问的属性设置成false就行了。我觉得这种方式太low,一点技术含量没有,完全体现不了我的水平果断pass了。

     接下来的方法就是窗体的委托:Form.Invoke(Delegate method, params object[] args);第一个参数是委托的方法,第二个参数就是委托方法的参数了。

     具体实现如下 :

    public void ShowMessage(string message,int type)

   {

this.Invoke(new Action<string>(delegate(string showmessage)
            {
                try
                {
                   
do something;

}
                catch (Exception e)
                {
                    MessageBox.Show(e.Message);
                }
            }), message);

  }

在上面的try中就可以正常的访问框体的控件了,至此大功告成,不喜勿碰!