国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

刨根問底U3D---關于Delegate的方方面面

2019-11-17 02:36:36
字體:
來源:轉載
供稿:網友

刨根問底U3D---關于Delegate的方方面面

我是否需要閱讀這篇文章

Code1:

1 PRivate delegate void BloodNumDelegate ();2 3 public delegate void ExpNumChangeDelegate (int _currentExpNum);4 5 public event ExpNumChangeDelegate mOnExpNumChangeDelegate;

Code2:

PlayerVoProxy.instance.mOnExpNumChangeDelegate += delegate(int _expNum){    Console.WriteLine ("阿呆收到, ExpNum is : {0}", _expNum);};

如果你可以很清楚明白上面兩部分代碼是什么意思,說明你已經很了解Delegate(至少比我了解:) ),

所以我想下面的文章也許對你的幫助不是很大. 不過如果某些地方你也有所疑惑,希望你能從我下面的文章中得到一些幫助.


這篇文章都包含哪些內容

這篇文章從最基本的Delegate開始介紹起,后續會引申到event, 匿名Delegate 及我個人對其使用的一點理解

提前需要閱讀的文章

如果你像我當初一樣對Delegate完全不理解,請先閱讀

NET之美:.NET關鍵技術深入解析.NET之美:.NET關鍵技術深入解析 迷你書 中的 第3章 (C# 中的委托和事件).

(作者對Delegate理解的及其深入,我是比不上了 :()


什么是 Delegate

從觀察者模式說起

觀察者模式大家肯定都不陌生

using System;using System.Collections;namespace L1{    public class FakeBloodChangeDelegate    {        public ArrayList mAllFakeDelegateListener;        public FakeBloodChangeDelegate ()        {            mAllFakeDelegateListener = new ArrayList ();        }        public void addListener (IFakeBloodNumChangeDelegateListener _listener)        {            mAllFakeDelegateListener.Add (_listener);        }        public void upldateListener ()        {            foreach (IFakeBloodNumChangeDelegateListener listener in mAllFakeDelegateListener)            {                listener.onBloodNumChange ();            }        }    }}
using System;namespace L1{    public interface IFakeBloodNumChangeDelegateListener    {        void onBloodNumChange ();    }}
using System;namespace L1{    public class Idiot : IFakeBloodNumChangeDelegateListener    {        public Idiot ()        {        }        public void onBloodNumChange ()        {            Console.WriteLine ("Idiot --> onBloodNumChange");        }    }}

using System;namespace L1{    public class TestArea1    {        private FakeBloodChangeDelegate mFakeBloodChangeDelegate;        private Idiot mIdiot;        public TestArea1 ()        {        }        public void run ()        {            mFakeBloodChangeDelegate = new FakeBloodChangeDelegate ();            mIdiot = new Idiot ();            mFakeBloodChangeDelegate.addListener (mIdiot);            mFakeBloodChangeDelegate.upldateListener ();        }    }}

這是一個比較標準的觀察者, idiot是監聽的人,當主體(FakeBloodChangeDelegate)發生變化時候調用 updateListener方法告訴所有監聽對象

Ok, 接下來讓我們稍微對這個FakeBloodChangeDelegate類進行一個簡單的封裝, 為其創建一個Player對象,Blood是Player的一部分

using System;namespace L1{    public class FakePlayerVoProxy    {        public FakeBloodChangeDelegate bloodNumChangeListner;        private int mCurrentBloodNum = 0;        public FakePlayerVoProxy ()        {            bloodNumChangeListner = new FakeBloodChangeDelegate ();        }        public void addPlayerBlood (int _addNum)        {            mCurrentBloodNum += _addNum;            bloodNumChangeListner.upldateListener ();        }    }}

于是,主類中的調用及變為:

using System;namespace L1{    public class TestArea1    {        private FakePlayerVoProxy mPlayerVo;        private Idiot mIdiot;        public TestArea1 ()        {        }        public void run ()        {            mPlayerVo = new FakePlayerVoProxy ();            mIdiot = new Idiot ();            mPlayerVo.bloodNumChangeListner.addListener (mIdiot);            mPlayerVo.addPlayerBlood (10);        }    }}

運行一下代碼,會得到和上面一樣的輸出。 畢竟其實只是簡單的對FakeBloodChangeDelegate進行一個封裝,沒有改變任何的代碼。

如果上面的例子可以完全理解,就讓我們往下繼續

Delegate 就是一個類

這個其實是一個很重要的信息,在上面提到的那本迷你書里面已經說的非常清楚了. 我之所以把代碼蹩腳的寫成這個模樣其實也是為了說明這件事。

上面例子中的FakeBloodChangeDelegate,包括對應的Listener可以簡化為一行代碼

public delegate void BloodNumChangeDelegate ();

先拋開public不說, 后面用 delegate void BloodNumChangeDelegate(); 相當于就是告訴編輯器為你創建出 一個

FakeBloodChangeDelegate 和IFakeBloodNumChangeDelegateListener (其實這塊是不準確的表達,不過目前可以先不要細糾結到時是怎么回事,當看完后面的內容后 可以回頭再去看 上面我提到的那本迷你書,里面講的很詳細)

using System;namespace L1{    public class FakePlayerVoProxy    {        public delegate void BloodNumChangeDelegate ();        public BloodNumChangeDelegate bloodNumChangeListner;        private int mCurrentBloodNum = 0;        public FakePlayerVoProxy ()        {        }        public void addPlayerBlood (int _addNum)        {            mCurrentBloodNum += _addNum;            bloodNumChangeListner ();        }    }}

注意

public delegate void BloodNumChangeDelegate (); 這行表示創建了FakeBloodChangeDelegate 類其實和 FackPlayerVoProxy這里類沒有任何關系,

完全可以單獨建立一個文件,起名Apple,然后把這行放在那個Apple的類里面不過根據這個類(Delegate)創建對象時候你就不能寫

public BloodNumChangeDelegate bloodNumChangeListner;

而要寫

public Apple.BloodNumChangeDelegate bloodNumChangeListner;

個人關于Delegate的一點理解

因為是寫AS出身(ActionSprite),所以對于回調函數一點都不陌生,而Delegate就可以理解為C#中的回調函數,唯一會比較費解的會是

public delegate void BloodNumChangeDelegate ();public BloodNumChangeDelegate bloodNumChangeListner;

這兩行代碼,這塊的核心就是要理解 Delegate其實就是告訴編譯器為你生成一個實現了觀察者模式的類.


關于Delegate前面的Public修飾符

之前我在解釋Delegate是怎么一回事時候,故意忽略掉了其前面的類修飾符 public. 這塊其實還是很有文章的.對于Delegate或者回歸本質,對于觀察者模式,最主要的三個函數應該是

addListener, removeListener, updateListener

而OO的思想就是 一定要封裝 對于外部監聽者 只應該能訪問到 addListener, removeListener 而upldateListner這個應該只有主類才可以做的事情.

讓我們先退回到實現Delegate之前的例子上面,繼續使用FakeBloodChangeDelegate ,

若要實現以上的需求,僅需要對應的將FakeBloodChangeDelegate改為private 并提供相應的public函數即可

using System;namespace L1{    public class FakePlayerVoProxy    {        private FakeBloodChangeDelegate mBloodNumChangeListner;        private int mCurrentBloodNum = 0;        public FakePlayerVoProxy ()        {            mBloodNumChangeListner = new FakeBloodChangeDelegate ();        }        public void addListener(IFakeBloodNumChangeDelegateListener _listener)        {            mBloodNumChangeListner.Add(_listener);        }        public void removeListener(IFakeBloodNumChangeDelegateListener _listener){//對應Remove代碼}                 public void addPlayerBlood (int _addNum)        {            mCurrentBloodNum += _addNum;            bloodNumChangeListner.upldateListener ();        }    }}

這塊應該很好理解吧? 所以呢如果使用Delegate去實現同樣的操作及可以寫成:

using System;namespace L1{    public class FakePlayerVoProxy    {        public delegate void BloodNumChangeDelegate ();        private BloodNumChangeDelegate bloodNumChangeListner;        private int mCurrentBloodNum = 0;        public FakePlayerVoProxy ()        {        }        public void addListener (?? _listener)        {            bloodNumChangeListner += _listener;        }                    public void addPlayerBlood (int _addNum)        {            mCurrentBloodNum += _addNum;            bloodNumChangeListner ();        }    }}

你會發現 在addListener這里 不知道該怎么寫了(其實是可以寫的,不過如果這塊你都理解怎么寫了也就不用再繼續往下讀啦 哈),這個 _listener應該是什么類型呢?


使用Event關鍵字

在推薦的那本迷你書里面(什么?! 還沒看...) 已經把這塊說的非常明白了, 為了封裝Delegate,對外僅提供add,remove 但是不提供

update方法, 但是如果不寫成public 又沒辦法對外訪問,所以及產生了 Event這個關鍵字

using System;namespace L1{    public class FakePlayerVoProxy    {        public delegate void BloodNumChangeDelegate ();        public event BloodNumChangeDelegate bloodNumChangeListner;        private int mCurrentBloodNum = 0;        public FakePlayerVoProxy ()        {        }        public void addPlayerBlood (int _addNum)        {            mCurrentBloodNum += _addNum;            bloodNumChangeListner ();        }    }}

using System;namespace L1{    public class TestArea1    {        private FakePlayerVoProxy mPlayerVo;
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 丰顺县| 龙山县| 衡阳县| 九江县| 梁山县| 上高县| 高尔夫| 区。| 襄垣县| 凉山| 定西市| 安西县| 吉林省| 墨江| 林西县| 登封市| 潼关县| 洛扎县| 屏南县| 红安县| 宕昌县| 嘉荫县| 微博| 罗源县| 上虞市| 康保县| 铜川市| 长汀县| 金湖县| 英吉沙县| 泸水县| 共和县| 陇川县| 蒲江县| 南丰县| 广宁县| 大余县| 安顺市| 蓬溪县| 佛坪县| 独山县|