Today I stumbled upon an interesting bug I wrote. I have a set of properties which can be set through a general setter. These properties can be value types or reference types.
public void SetValue( TEnum property, object value ) { if ( _properties[ property ] != value ) { // Only come here when the new value is different. } }
When writing a unit test for this method I found out the condition is always true for value types. It didn't take me long to figure out this is due to boxing/unboxing. It didn't take me long either to adjust the code to the following:
public void SetValue( TEnum property, object value ) { if ( !_properties[ property ].Equals( value ) ) { // Only come here when the new value is different. } }
The thing is I'm not entirely satisfied with this solution. I'd like to keep a simple reference comparison, unless the value is boxed.
The current solution I am thinking of is only calling Equals()
for boxed values. Doing a check for a boxed values seems a bit overkill. Isn't there an easier way?
If you need different behaviour when you're dealing with a value-type then you're obviously going to need to perform some kind of test. You don't need an explicit check for boxed value-types, since all value-types will be boxed** due to the parameter being typed as object
.
This code should meet your stated criteria: If value
is a (boxed) value-type then call the polymorphic Equals
method, otherwise use ==
to test for reference equality.
public void SetValue(TEnum property, object value) { bool equal = ((value != null) && value.GetType().IsValueType) ? value.Equals(_properties[property]) : (value == _properties[property]); if (!equal) { // Only come here when the new value is different. } }
( ** And, yes, I know that Nullable<T>
is a value-type with its own special rules relating to boxing and unboxing, but that's pretty much irrelevant here.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With