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: private Dictionary> _nullChecks = new Dictionary>(); 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; }); } And your check would be like: public void SetParameterValue(SqlParameter parameter, object parameterValue, bool isNullable) { if (_nullChecksparameterValue.GetType().
Invoke(parameterValue, isNullable)) parameter. Value = DBNull. Value; else parameter.
Value = parameterValue; } Although, as suggested by others, changing the code to use the Nullable type would be better.
You could always do Protected void SetParameterValue(SqlParameter parameter, object parameterValue, bool isNullable).... 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 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. This condenses your type validation and all your overloads, and it removes the need for a generic method too.
I was wondering the same thing... I'd probably also try to replace NULL_STRING, NULL_INT etc. With Nullable or null where applicable. – Kevin Wienhold Nov 24 '10 at 15:53 I don't find it a good practice to pass around "object" types, and there's lot of boxing/unboxing. Isn't there something with generics that can accomplish the same thing, but without having to create a giant switch statement with each type?
– Daniel Perez Nov 24 '10 at 15:57 Well you're still going to box because parameter. Value takes an object. – Kevin Nov 24 '10 at 15:59 1 The conditional statement is going to be difficult to get around, because you are eventually going to have to ask the "What type is this object?
" and when you get the answer, you have enact certain validation rules. It all comes down to if this is X, then do this.It just all depends on where you are going to ask the question, in your example, your still doing it, you've just separated out the logic between methods. – Kevin Nov 24 '10 at 16:03.
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: 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; } This presupposes that parameterValue can be re-cast without too much hassle, of course.
I think you can use nullable types instead of bool isNullable. Protected void SetParameterValue(SqlParameter parameter, T parameterValue) { if (parameterValue == null) parameter. Value = DBNull.
Value; else parameter. Value = parameterValue; } And possibly call it accordingly with this signature. Like SetParameter(param,null) SetParameter(param,5).
You are not addressing the fact that value types cannot be null. – Klaus Byskov Hoffmann Nov 24 '10 at 15:53 Wait a second, you mean SetParameter(param,null) won't work? – Jenea Nov 24 '10 at 15:54 yes, but SetParameter won't.
Since value types can't be null parameterValue == null will always be false. – Kevin Nov 24 '10 at 15:55 @Kevin well, but in this case int parameter won't be equal to NULL_INT (in question) – Jenea Nov 24 '10 at 16:00 @jenea, except that isn't in your validation logic, someone can still do SetParameterValue.... and validate a null value to true. It doesn't matter that there are other options to add an int value.
The generic method provided allows that to occur. – Kevin Nov 24 '10 at 16:05.
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: protected void SetParameterValue(SqlParameter parameter,object parameterValue){ if(IsParameterNull(parameterValue) && parameter. IsNullable){ parameter. Value = DBNull.
Value; } else{ parameter. Value = parameterValue; } } List nulls = new List(){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; } The job here is to create a NULLTYPE class that encapsulates your concepts of null and them the nulls.
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.
Another thing that I forgot to say is that if you really want to code a good code start by reading Clean Code tinyurl. Com/3xyq2ob. It's not a bible and I'm not an evangelist, but it'll open your mind or at least help a little =D – vnavarro Nov 24 '10 at 16:37 This seems like an interesting solution, although I'm not sure I understand what the NULLTYPE class looks like.
How does List.Contains() work when comparing an Object to a NULLTYPE? Casting operators? And how does it take into account things like checking if a (non-value type) is actually null?
Don't you at some point just end up with a switch statement in NULLTYPE anyway? – Grant Crofton Nov 24 '10 at 16:52 Unfortunatelly in somewhere at some point we will end up with either a reconstruction of types and its meanings of nulls or a switch statement. That is why I told this is a question on how much work do you want to put on it.
NullType class depends on the developer desires, it could be as simple as: – vnavarro Nov 25 '10 at 17:25 public NullType{ protected object nullValue; public NullType(object nullValue){ this. NullValue = nullValue; } } Following this idea the List.Contains() method is only checking if the parameterValue is "equals" to a NULLTYPE. And yeah he is casting operators, it's very difficult (not impossible) to get away from casting, swicthing or anything like this without re-create your types to tell them what is to be null and even further to do this receiving generic values.
– vnavarro Nov 25 '10 at 17:33 By the way I liked your solution, I read it just before I answered your comment here. – vnavarro Nov 25 '10 at 17:53.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.