将大量方法重载转换为通用方法,设计问题
我试图在这里重构其他人之前完成的一些代码,因为我发现它非常不切实际 这是一个例子
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)
,但是,我不知道什么是最好的方法,我可以在这个通用方法中封装什么,以及我还需要在单独的方法中做什么。值得吗?或者“很多方法”的方法可以吗?我将从通用产品中获得什么?谢谢!
I'm trying to refactor some code here that was done previously by other guys, since i find it quite unpractical
Here's an example
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;
}
Like those, there are a lot more. Now i needed to create one that accepts a new type (which doesn't have a method for it yet) and decided that maybe i could clean up a bit, make this better.
my idea is to create something like
protected void SetParameterValue<T>(SqlParameter parameter, T parameterValue, bool isNullable)
however, i don't know what's the best approach, what can i encapsulate inside this generic method and what will i need to do in separate methods as well. Is it worth it? or the "lots of methods" approach is fine? what would i gain from the generic one? thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
消除对开关的需要的一种方法是使用某种字典来保存委托,该委托确定每种可能类型的 null 构成。尽管我认为你必须坚持这个目标。因此,您将拥有一本字典并将其设置为:
您的检查将类似于:
尽管按照其他人的建议,更改代码以使用 Nullable 类型会更好。
One way of removing the need for switches would be to use some kind of dictionary to hold delegates which determine what constitutes null for each possible type. Although I think you'd have to stick with object for this. So you'd have a dictionary and set it up like:
And your check would be like:
Although, as suggested by others, changing the code to use the Nullable type would be better.
您始终可以使用
parameter.Value
获取一个对象,因此减去每种类型的验证,您实际上不需要将它们分开。您可以创建一个验证参数方法,该方法反映并提取参数的类型类型,并检查是否针对该类型设置了空值。
这样
可以压缩类型验证和所有重载,并且也消除了对泛型方法的需要。
You could always do
parameter.Value
takes an object so minus the validation for each type, you don't really need to seperate them out.You could create a validate parameter method which reflects and pulls type type for the parameter and checks if the null value is set against that type.
something like
This condenses your type validation and all your overloads, and it removes the need for a generic method too.
方法定义的“多重签名”方法非常好——它给了我们多态性。就我个人而言,我更愿意保留该技术而不是按照您的建议进行重构。
然而,我想要做的是用对“master”方法的调用来替换除了一个方法体之外的所有方法体的重复,从而转换参数:
这预设了
parameterValue
当然,可以重新铸造,没有太多麻烦。The 'multiple signatures' approach to method definition is perfectly fine - it's what gives us polymorphism. Personally, I'd prefer to keep that technique rather than refactor as you suggest.
However, what I would do is replace the repetition of the method body in all but one with calls to the 'master' method, casting the parameter thus:
This presupposes that
parameterValue
can be re-cast without too much hassle, of course.我认为您可以使用可空类型而不是 bool isNullable。
并可能用此签名相应地调用它。
喜欢
设置参数(参数,空)
设置参数(param,5)
I think you can use nullable types instead of bool isNullable.
And possibly call it accordingly with this signature.
Like
SetParameter(param,null)
SetParameter(param,5)
最后很难用 switch/if 语句“消除”这个问题,必须有人去做。
您可以选择覆盖/封装对象或类的 null 值,但您仍然必须检查每个概念中的 null 值。
我不知道这是否会让事情变得更好,但您可以首先通过创建前面所说的方法来隔离重复,或者仅隔离空值检查。最后一个是我所做的:
这里的工作是创建一个
NULLTYPE
类来封装 null 的概念,并且nulls.Contains(parameterValue)
检查是否值存在于列表中。您可以进一步重写
Contains
来检查您自己的方式,但您必须考虑您想要在这方面花费多少工作。It's difficult to "remove" the question with switch/if statments in the end, someone have to do it.
You have the option of override/encapsulate what is null for an object or a class, but you'll still have to check what is null in each concept.
I don't know if this make things better, but you can first isolate the repetition by creating a method as said before or isolate only the nulls checking. The last one is what I did bellow:
The job here is to create a
NULLTYPE
class that encapsulates your concepts of null and them thenulls.Contains(parameterValue)
checks if the value exists in the list.You can go further and override
Contains
to check on your own way, but you have to think how much work do you want to spend on this.