2010-11-24 42 views
3

我試圖重構這裏一些代碼,被其他人以前做的,因爲我覺得很不切實際 下面是一個例子轉換很多方法重載成一個通用的方法,設計問題

protected void SetParameterValue(SqlParameter parameter, string parameterValue, bool isNullable) 
{ 
    if ((null == parameterValue || parameterValue == NULL_STRING) && isNullable) 
      parameter.Value = DBNull.Value; 
    else parameter.Value = parameterValue; 
} 

protected void SetParameterValue(SqlParameter parameter, int parameterValue, bool isNullable) 
{ 
    if (parameterValue == NULL_INT && isNullable) 
      parameter.Value = DBNull.Value; 
    else parameter.Value = parameterValue; 
} 

protected void SetParameterValue(SqlParameter parameter, Int64 parameterValue, bool isNullable) 
{ 
    if (parameterValue == NULL_LONG && isNullable) 
      parameter.Value = DBNull.Value; 
    else parameter.Value = parameterValue; 
} 

像那些,還有更多。現在我需要創建一個接受新類型的類型(目前還沒有方法),並且決定也許我可以清理一下,做得更好。 我的想法是創建一個類似

protected void SetParameterValue<T>(SqlParameter parameter, T parameterValue, bool isNullable) 

但是,我不知道什麼是最好的方法,我將需要不同的方法做的一樣好,我可以封裝這個泛型方法裏面是什麼,什麼。這值得麼?或「很多方法」的方法是好的?通用的我會得到什麼?謝謝!

+0

@Alex有點極端 – msarchet 2010-11-24 15:50:44

+0

由於Nullable類型現在可用,所以可以考慮刪除那些NULL_INT,NULL_LONG等常量,而只是使用`int?`,`long?`作爲數據類型。 – Heinzi 2010-11-24 15:52:39

+0

問題是,NULL_INT等在很多地方,我想執行一些快速重構,使事情變得更好一些,而不必更改很多代碼(並且有很多重新測試) – 2010-11-24 15:55:13

回答

3

消除開關需求的一種方法是使用某種字典來保存委託,這些委託確定每種可能類型的空值。雖然我認爲你必須堅持這個對象。因此,有你的字典,並設置它像:

private Dictionary<Type, Func<object, bool, bool>> _nullChecks = new Dictionary<Type, Func<object, bool, bool>>(); 

private void SetupNullChecks(){ 
    _nullChecks.Add(typeof(string), (object parameterValue, bool isNullable) => { return (null == parameterValue || parameterValue.ToString() == NULL_STRING) && isNullable; }); 
    _nullChecks.Add(typeof(int), (object parameterValue, bool isNullable) => { return (int)parameterValue == NULL_INT && isNullable; }); 
    _nullChecks.Add(typeof(long), (object parameterValue, bool isNullable) => { return (long)parameterValue == NULL_LONG && isNullable; }); 
} 

而且你的支票會是這樣:

public void SetParameterValue(SqlParameter parameter, object parameterValue, bool isNullable) 
{ 
    if (_nullChecks[parameterValue.GetType()].Invoke(parameterValue, isNullable)) 
     parameter.Value = DBNull.Value; 
    else parameter.Value = parameterValue; 
} 

雖然,別人的建議,改變代碼使用空類型會會更好。

1

你總是可以做

Protected void SetParameterValue(SqlParameter parameter, 
object parameterValue, bool isNullable).... 

parameter.Value需要一個對象,因此減爲每種類型的驗證,你並不真的需要它們分開了。

您可以創建一個驗證參數方法,它反映併爲參數提取類型類型,並檢查是否針對該類型設置了空值。 像

bool IsNull (object value){ 
    if (value is int){ 
    check int.. 
    } 
} 
//this is a quick and dirty example, there are more elegant ways to handle it. 

這其中凝聚你的類型的驗證和所有的過載,並刪除了一個通用的方法也需要。

0

我認爲你可以使用可空類型而不是bool isNullable。

protected void SetParameterValue<T>(SqlParameter parameter, T parameterValue) 
{ 
if (parameterValue == null) 
    parameter.Value = DBNull.Value; 
else 
    parameter.Value = parameterValue; 
} 

並可能使用此簽名相應地調用它。 像 的setParameter(PARAM,NULL) 的setParameter(PARAM,5)

0

的 '多個簽名' 的方式方法定義是完全沒有問題 - 這是什麼使我們的多態性。就我個人而言,我寧願保留這種技術,而不是像你所建議的那樣重構。

不過,我要做的就是用替換法體在所有重複,但一個與調用「主」的方法,從而鑄造參數:

protected void SetParameterValue(SqlParameter parameter, int parameterValue, bool isNullable) 
{ 
    SetParameterValue(parameter, (Int64)parameterValue, isNullable); 
} 
protected void SetParameterValue(SqlParameter parameter, Int64 parameterValue, bool isNullable) 
{ 
    if (parameterValue == NULL_INT && isNullable) 
    parameter.Value = DBNull.Value; 
    else 
    parameter.Value = parameterValue; 
} 

這預示着parameterValue能當然,沒有太多的麻煩重新演繹。

0

很難用開關「去除」問題/如果最後發表的話,有人必須這樣做。 您可以選擇覆蓋/封裝對象或類的null值,但仍然必須檢查每個概念中的null值。

我不知道這是否會讓事情變得更好,但是您可以先通過創建方法來隔離重複,或者只隔離空值檢查。最後一個是我做的波紋管:

protected void SetParameterValue(SqlParameter parameter,object parameterValue){ 
    if(IsParameterNull(parameterValue) && parameter.IsNullable){ 
     parameter.Value = DBNull.Value; 
    } 
    else{ 
     parameter.Value = parameterValue; 
    } 
} 

List<NULLTYPE> nulls = new List<NULLTYPE>(){new NULLTYPE(NULL_INT), new NULLTYPE(NULL_LONG), new NULLTYPE(null)} 
protected bool IsParameterNull(object parameterValue){ 
    if(nulls.Contains(parameterValue)) return true; 
    else return false; 
} 

這裏的工作是創建一個NULLTYPE類,它封裝你的空概念,他們nulls.Contains(parameterValue)檢查列表中的存在價值。 你可以進一步去覆蓋Contains以自己的方式進行檢查,但是你必須考慮你需要花費多少工作。