你有很多東西與此代碼回事。我完全重寫了它,這不是最簡單的代碼,甚至也不是最好的代碼,但它是爲了說明需要了解更多或正在處理的領域。
研究異常處理,尤其是何時使用它以及如何使用它。切勿寫入吞噬錯誤的嘗試塊。如果此方法返回null,你打算做什麼?表名是不好的?連接失敗了嗎?用戶可能會也可能不會修復這個錯誤,但是您會吞噬它。現在沒有人知道它是什麼。
更糟糕的是,甚至可能沒有人知道在這裏發生的錯誤取決於您對null做了什麼。永遠不要吞下這樣的錯誤。應用程序應該在發生錯誤的地方失敗。還要小心返回這樣的空值。當您返回空值,然後執行其他操作時,應用程序可能會在某個地方出現故障,而原始錯誤現在很難找到並修復。編寫框架時,您可能偶爾會以這種風格返回空值。對於普通的應用程序,通常不需要它,幾乎也不是一個好主意。
良好質量的生產代碼通常只包含很少的異常處理,因爲您應該使用條件來處理任何您可以預見的事情。任何你無法預見的東西通常也無法處理。你可能有很多嘗試...... finally塊存在清理資源,但一個應用程序應該包含很少的實際try..catch黑色。通常,您會讓錯誤傳播回調用堆棧,最終處理程序在應用程序關閉之前通知用戶。
以下仍然不是您可以編寫的最佳代碼。我保持原來的合理性,並刪除了一些快捷方式,使其更清晰。研究差異,並從那裏去
public class SomeClass
{
//Use parameters rather than accessing module level properties
private IList<ColumnInformation> GetColumnInformationForTable(string dbName, string tableName)
{
// Favor object oriented styles and meaningful names. Your method does not return a list of tables
// it returns a list of column meta data
List<ColumnInformation> columnInformations = new List<ColumnInformation>();
// Avoid SQL conncatenation if at all possible. NEVER concatenate where parameters into SQL commands and NEVER EVER with single quotes.
// Here table name requires concatenation but the select parameter TableName does not.
string selectCmdString = "SELECT column_name,data_type,character_maximum_length FROM " + dbName + ".information_schema.columns WHERE table_name = @TableName";
// Use parameters. Get everything ready first, don't open connections prematurely and only wrap error prone code in try blocks.
SqlCommand cmd = new SqlCommand(selectCmdString, conn);
SqlParameter tableNameParameter = new SqlParameter("@TableName", tableName);
cmd.Parameters.Add(tableNameParameter);
// Use a DataReader since you cannot modify this data anyway.
// This also shows an appropriate use of a try block to ensure a connection gets closed,
// but better yet, open your reader with the CommandBehavior set to close
// and get rid of this try block altogether
try
{
//Reconsider use of a module or global level connection. May be better to create a new here.
conn.Open();
SqlDataReader reader = cmd.ExecuteReader();
//Favor OOP styles rather than indexes and arrays and repeated calls to determine things like Rows.Count in a loop
while(reader.Read())
{
// Favor explicit member access rather than index acess.
//YOUR HOMEWORK! Study DataReader access and rewrite the code below to handle possible nulls in length field. Use a method based on evaluating conditionals, DO NOT use a method based on a try block.
ColumnInformation columnInformation = new ColumnInformation(reader["column_name"].ToString(), reader["data_type"].ToString(), (int)reader["character_maximum_length"].ToString());
columnInformations.Add(columnInformation);
}
reader.Close();
}
finally
{
// The only reason to use the try is to make sure the connection gets closed here. A better approach
// is to use the CommandBehavior.CloseConnection option and get rid of the try finally block completely.
// But NEVER just wrap a bunch of code in try blocks arbitrarily, swallow any errors and return a null.
conn.Close();
}
return columnInformations;
}
}
public class ColumnInformation
{
private string _columnName;
private string _dataType;
private int _columnLength;
public string ColumnName
{
get { return _columnName; }
}
public string DataType
{
get { return _dataType; }
}
public int ColumnLength
{
get { return _columnLength; }
}
public ColumnInformation(string columnName, string dataType, int columnLength)
{
_columnName = columnName;
_dataType = dataType;
_columnLength = columnLength;
}
}
感謝很多...這真的很有幫助。幫助我重新思考我的編碼方法和標準。現在必須重新排列我的代碼。 ThnQ – NewBie 2011-03-13 08:22:23