2010-07-29 65 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