我正在尝试重构一些以前由其他人完成的代码,因为我发现它非常不实用 这是一个例子
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 :(得分:3)
消除交换机需求的一种方法是使用某种字典来保存委托,这些委托确定每种可能类型的构成null的内容。虽然我认为你必须坚持使用对象。所以你有一本字典并设置如下:
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;
}
尽管如其他人所建议的那样,更改代码以使用Nullable类型会更好。
答案 1 :(得分:1)
你可以随时
Protected void SetParameterValue(SqlParameter parameter,
object parameterValue, bool isNullable)....
parameter.Value
接受一个对象,因此减去每种类型的验证,你真的不需要将它们分开。
您可以创建一个validate参数方法,该方法反映并提取参数的类型类型,并检查是否针对该类型设置了null值。
之类的东西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.
这会压缩您的类型验证和所有重载,并且它也不再需要通用方法。
答案 2 :(得分:0)
我认为你可以使用可空类型而不是bool isNullable。
protected void SetParameterValue<T>(SqlParameter parameter, T parameterValue)
{
if (parameterValue == null)
parameter.Value = DBNull.Value;
else
parameter.Value = parameterValue;
}
并可能使用此签名相应地调用它。 喜欢 的setParameter(PARAM,空) 的setParameter(PARAM,5)
答案 3 :(得分:0)
方法定义的“多重签名”方法非常好 - 它是赋予我们多态性的东西。就个人而言,我更愿意保留这种技术,而不是像你建议的那样重构。
然而,我 所做的是用“master”方法调用替换方法体的重复,然后通过调用参数来替换:
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
可以在没有太多麻烦的情况下重新演绎。
答案 4 :(得分:0)
很难用switch / if“删除”这个问题,最后有人必须这样做。 您可以选择覆盖/封装对象或类的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
类来封装你的null概念,nulls.Contains(parameterValue)
检查列表中是否存在值。
你可以更进一步覆盖Contains
以自己的方式检查,但你必须考虑你想花多少钱在这上面。