我正在从事一个以 Oracle 数据库为中心的项目(尽管老实说我并不认为这很重要),我发现自己有大量重复的代码,特别是例外。到目前为止我看到的最好的方法是来自这个问题https://stackoverflow.com/a/1554/865868,它建议使用代表。在我尝试在我的项目中实现它之前,这看起来像是一个完美的解决方案。我发现我有一个不实用的案例。
让我稍微描述一下我的程序。我有两段代码处理数据库操作。这个想法是我调用一个返回 DataTable 的函数,称为 LoadDataTable()。然后我有一个函数可以将列表中的项目插入到表中。
private void AddToList(List<string> itemList) {
try {
using (OracleConnection connection = new OracleConnection(connectionString)) {
connection.Open();
foreach (string item in itemList) {
using (OracleCommand command = new OracleCommand()) {
command.Connection = connection;
//Insert operation here
//......
command.ExecuteNonQuery();
}
}
} catch (OracleException ex) {
string messageboxtitle = "Database Exception";
switch (ex.Number) {
case 00001:
MessageBox.Show("Constraint Violation Error", messageboxtitle, MessageBoxButtons.OK);
break;
case 12154:
MessageBox.Show(string.Format("Connection Error: {0}", ex.Message), messageboxtitle);
break;
default:
MessageBox.Show(ex.ToString());
break;
}
}
}
private DataTable LoadDataTable() {
DataTable dataTable = new DataTable();
try {
using (OracleConnection connection = new OracleConnection(connectionString)) {
connection.Open();
using (OracleCommand command = new OracleCommand()) {
command.Connection = connection;
command.CommandText = sql;
command.CommandType = CommandType.Text;
using (OracleDataAdapter oda = new OracleDataAdapter(command)) {
oda.Fill(dataTable);
}
}
}
} catch (OracleException ex) {
string messageboxtitle = "Database Exception";
switch (ex.Number) {
case 12154:
MessageBox.Show(string.Format("Connection Error: {0}", ex.Message), messageboxtitle); //Duplicate Exception
break;
default:
MessageBox.Show(ex.ToString());
break;
}
}
return dataTable;
}
请记住,我必须重写和简化该代码,以便我可以讨论它。无论如何,看着委托示例,我很快意识到参数是一个问题。您不能将参数用于List<string>
类型,但毫无疑问代表的有用性,因为我可以将一个集中的部分用于不重复的异常。
private delegate void DatabaseOperation(List<string> itemList);
private void PerformDatabaseOperation(DatabaseOperation operation, List<string> itemList){
try {
operation(itemList);
} catch (OracleException ex) {
string messageboxtitle = "Database Exception";
switch (ex.Number) {
case 00001:
MessageBox.Show("Constraint Violation Error", messageboxtitle, MessageBoxButtons.OK);
break;
case 12154:
MessageBox.Show(string.Format("Connection Error: {0}", ex.Message), messageboxtitle);
break;
default:
MessageBox.Show(ex.ToString());
break;
}
}
}
private void AddToList(List<string> itemList) {
using (OracleConnection connection = new OracleConnection(connectionString)) {
connection.Open();
foreach (string item in itemList) {
using (OracleCommand command = new OracleCommand()) {
command.Connection = connection;
//Insert operation here
//......
command.ExecuteNonQuery();
}
}
}
如何使用:
List<string> itemList = new List<string>();
//code to fill list
PerformDatabaseOperation(AddToList, itemList);
现在的问题是我无法使用此委托实现 LoadDataTable(),因为它没有任何参数。由于 List 不兼容,委托上的使用params
不起作用。我正在寻求改进我的编码技术以提高可重用性和可读性,但我发现自己在旋转我的轮子阅读有关该主题的各种线程,主要是因为除了一个没有真正抓住问题的简单示例之外,它们还不够深入我发现自己现在拥有。为了确保这个问题得到解答,让我提出最后一个问题。我怎样才能编写避免重复异常的代码?
更新
对于希望解决类似问题的任何人,请参见下文。保持我的状态,还有很多可以改进代码的方法。此外,任何对此处讨论的var
关键字的讨论感兴趣的人,请转到此处。我希望这有帮助:
private delegate void DatabaseOperation();
private void PerformDatabaseOperation(DatabaseOperation operation) {
try {
operation();
} catch (OracleException ex) {
string messageboxtitle = "Database Exception";
switch (ex.Number) {
case 00001:
MessageBox.Show("Constraint Violation Error", messageboxtitle, MessageBoxButtons.OK);
break;
case 12154:
MessageBox.Show(string.Format("Connection Error: {0}", ex.Message), messageboxtitle);
break;
default:
MessageBox.Show(ex.ToString());
break;
}
}
}
private void AddToList(List<string> itemList) {
using (OracleConnection connection = new OracleConnection(connectionString)) {
connection.Open();
foreach (string item in itemList) {
using (OracleCommand command = new OracleCommand()) {
command.Connection = connection;
//Insert operation here
//......
command.ExecuteNonQuery();
}
}
}
private DataTable LoadDataTable() {
DataTable dataTable = new DataTable();
using (OracleConnection connection = new OracleConnection(connectionString)) {
connection.Open();
using (OracleCommand command = new OracleCommand()) {
command.Connection = connection;
command.CommandText = sql;
command.CommandType = CommandType.Text;
using (OracleDataAdapter oda = new OracleDataAdapter(command)) {
oda.Fill(dataTable);
}
}
}
return dataTable;
}