2010-11-24 40 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以自己的方式进行检查,但是你必须考虑你需要花费多少工作。