2010-07-29 79 views
6

我想爲我們在這裏開發的幾個應用程序開發一個框架,我試圖構建的框架類之一是用於創建數據庫。理想情況下,我會有一個方法,我可以通過它以下兩種方法:CreateDatabaseTables()和ResetDatabaseValues();例如,我可能有三個應用程序,我將調用Application1,Application2和Application3;每一個這些應用程序都會有不同的數據庫模式,我會將它們合併到代碼中(例如,CreateDatabaseTables有一堆「創建表」命令)。我想創建一個可以通過每一種被利用,因此會看起來像一個單一的數據庫的方法:傳遞多個方法(委託?)

應用1

BuildLocalDatabase(CreateTablesForApp1(),ResetDatabaseValuesforApp1()) 

應用2

BuildLocalDatabase(CreateTablesForApp2(),ResetDatabaseValuesforApp2()) 

Application3

BuildLocalDatabase(CreateTablesForApp3(),ResetDatabaseValuesforApp3()) 

BuildLocalDatabase方法會執行如下操作:

publid bool BuildLocalDatabase(CreateTablesForApp(),ResetDatabaseValuesforApp()) 
{ 
    - see if database file exists; if it does, delete it 
    - create a new database file 
    - call CreateTablesForApp 
    - if the tables were created successfully, call ResetDatabaseValuesForApp 
} 

任何想法,我將如何去做到這一點。在BuildLocalDatabase函數中實際上有一堆驗證和其他的東西,我的目標顯然是最小化每個應用程序中重複代碼的數量......關於如何去做這件事的任何建議。我認爲在C++中,我可以通過CreateTablesForApp和ResetDatabaseValuesForApp方法作爲函數點,但似乎沒有辦法在C#中執行此操作。代理似乎處理得很好,因爲我實際上只限於一種方法(並且多播似乎想要兩次運行這些方法)。

+1

您可能需要考慮格式化問題中的代碼,以便人們可以更輕鬆地閱讀它。 – 2010-07-29 17:24:19

回答

4

你要使用委託:

public bool BuildLocalDatabase(Func<Database, bool> createTables, Action<Database> resetValues) 
{ 
    // Do initialization 
    if (createTables(db)) 
    { 
      resetValues(db); 
    } 
} 

你會再調用這個爲:

BuildLocalDatabase((db) => CreateTablesForApp1(), (db) => ResetDatabaseValuesforApp1()); 

(我把在「數據庫」參數的情況下,你需要它 - 如果你不用,你可以使用Func<bool>Action,沒有這個參數,直接傳遞方法名來代替lambda表達式。通常像這樣的方法需要某種形式的參數,比如數據庫連接等等,所以我把它放進去。)

+0

裏德, 感謝您的回覆 - 這是完美的。 然而,在思考這個問題時,我想知道你是否會以這種方式或不同的方式來解決問題(因爲你回答了我的原始問題「spot on」,我會做出假設,你知道我是什麼試圖做)。 那麼,你認爲我應該使用你描述的「Func」方法還是創建一個「基礎」數據庫類,我可以爲每個應用程序「派生」一個新類。這個「派生」類將有「應用程序特定的」代碼... 再次感謝... – user405965 2010-07-29 22:24:56

+0

@ ed92620:這真的取決於。使用類(或接口!)代替2個代表可能更合適,但也可能不是。沒有更多的詳細信息和對項目的瞭解,很難知道什麼是最好的。就個人而言,如果代碼量很小,我喜歡代表 - 如果它很大,使用類可能更好,如果沒有其他原因,而不是可測試性更強。 – 2010-07-29 23:11:20

1

嗯,基本上可以。如果問題是關於委託syntac,你需要減掉幾(),並定義了一個代理:

public delegate void MyDelegate(); 

publid bool BuildLocalDatabase(MyDelegate CreateTablesForApp, MyDelegate ResetDatabaseValuesforApp) 
{ 
    CreateTablesForApp(); 
    ... 
    ResetDatabaseValuesforApp(); 
} 

,並調用它像:

BuildLocalDatabase(CreateTablesForApp1,ResetDatabaseValuesforApp1); 
+2

對於這樣的空白代表,不應該只使用內置委託'Action'? – 2010-07-29 17:31:16

+0

@戈登:是的,但我決定展示所涉及的完整語法。 – 2010-07-29 17:48:20

+1

在大多數情況下,我更喜歡完整的委託語法 - 正確命名的委託告訴程序員關於委託的用途以及應該如何實現的內容。一個普通的「Action」沒有這個描述 - 你最終將它留給實例名稱來描述它 - 但實例應該描述它自己。 – 2010-07-29 17:56:43