看板 C_Sharp 關於我們 聯絡資訊
Dictionary<Tkey,Titem> + delegate MSDN中有提到用Dictionary裝delegate的方法 自己拿來變化了一下 http://msdn.microsoft.com/zh-tw/library/z4ka55h8(v=VS.90).aspx accessor-declarations 的用法之一是公開大量的事件但不配置每個事件的欄位 ,而是改用字典來儲存事件執行個體。 不過,這只在您擁有大量的事件,但預期大多數事件都不會實作的情況下才有用。 不過.... 我想請問紅字部分為什麼會這樣說? 自己在想stg的演算法時 想了一些東西: 1.物件移動時,至少有位置、速度、加速度等三個變數要處理 所受到的因素不只一種,而且形式也不一定 重力場:需連結到另一個位置,計算距離後求得受力 由於位置會變,所以要用ref連結到目標 這必須每次計算 空氣阻力:固定往後方,要取的物件的姿勢去計算 用極座標較方便 且也是必須每次都計算 特殊移動方式: 假設我設計一個叫做「後燃器」的功能 能在五秒內向前方提供+3的加速度 這在處理起來很麻煩 我必須宣告一個欄位記錄這個方法用的時間參數 而且也沒辦法同時要使用多個後燃器 也是每個影格都要計算 下略........... 2.另外關於持續性特效之類的 如果用下面這種寫法也是很麻煩的事,很不乾淨,看了覺得討厭: if (is中毒) this.中毒效果(); if (is暈眩) this.暈眩效果(); 下略................ 3.委派本身就有限制型別,如果該方法必須給予參數 而我的委派不是同個參數類型,那就必須用匿名函式 雖然上面那種問題可以寫個委派或是事件解決 但這會造成移除時的困難 而且,委派或匿名方法,沒辦法預先丟變數下去 即使用匿名方式放變數下去,之後變數被更動時,執行內容也會跟著變 例如: for (int i=0;i<5;i++) { 委派1 += () => {Console.Write(i)} } 執行 委派1 時,出來的會是55555,而不是01234 ======================================================================= 所以,基於: 1.能事先塞不同變數下去,讓委派執行 且在原函式中的變數受到更動時,不會跟著變 2.能輕易移除,或是自主移除 3.寫程式上很簡潔,且共用範圍廣 所以我想了用Dictionary<T,T>去裝匿名方法的辦法 如果是在STG中的話,我只要在建立新變因時 (例如在場上新增一個重力場) 就對所有場上物件底下的「控制位置的class」 下達 以「重力場的參照(ref)」計算吸引力的命令 那麼,只要我在Update()中執行所有字典下的委派,就能達到這個效果了 ======================================================================= http://nopaste.csie.org/38d94 public delegate void 委派(); public class Test { private int id = 0; private int ID { get { return id++; } //避免ID重覆 } private Dictionary<int, 委派> 待執行的程式字典 = new Dictionary<int, 委派>(); public int 我是控制方法的方法(int 次數,string 代號) { int i = 0; int 這次方法的執行ID = ID; 待執行的程式字典.Add( 這次方法的執行ID, () => { if (i++ < 次數) 我是要執行的程式(代號, i); else { 待執行的程式字典.Remove(這次方法的執行ID); Console.WriteLine("移除了:{0}", 代號); } } ); return 這次方法的執行ID; } private void 我是要執行的程式(string 代號,int 次數) { Console.WriteLine("執行了:{0} 第{1}次", 代號, 次數); } public bool 執行所有字典中的程式() { if (待執行的程式字典.Count == 0) return true; //如果有方法被移除,會造成位在後方的索引往前移,所以要從後面開始執行 for (int i = 待執行的程式字典.Count-1; i > -1; i--) { //注意,不可用「待執行的程式字典[i]」去取得方法,因為[]中是Tkey 待執行的程式字典.ElementAt(i).Value(); } return false; } } class Program { static void Main(string[] args) { Test A = new Test(); A.我是控制方法的方法(3, "方法一"); A.我是控制方法的方法(2, "方法二"); A.我是控制方法的方法(4, "方法三"); int i = 1; bool is結束; while (true) { Console.WriteLine("第 {0} 次執行A的字典集。",i); is結束 = A.執行所有字典中的程式(); Console.WriteLine("==============================="); Console.WriteLine(); if (is結束) break; i++; } Console.WriteLine("執行完畢"); } } -- ◢ 鄉民啊!鄉民! 請告訴我誰是最純潔的人! ◢█ │ PTT │ ██ :就是你!Snow White F23ko!│ █◤ ╯ ◤ ﹨(╯▽╰ )∕ -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 163.27.109.99 ※ 編輯: F23ko 來自: 163.27.109.99 (03/31 20:09) ※ 編輯: F23ko 來自: 163.27.109.99 (03/31 20:10)
help0430:第一二點可以參考某些設計模式,第三點可以參考Action<T> 04/07 12:28
F23ko:已經寫出來了啊! 就是我這一篇的code。我是在擔心效率問題.. 04/07 23:08
F23ko:匿名函式的話.... 只要包函那個函式的{}中的資源都不會被釋 04/07 23:09
F23ko:放的樣子....似乎很占記憶體 04/07 23:10