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
valueis a (boxed) value-type then call the polymorphicEqualsmethod, otherwise use==to test for reference equality.( ** 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.)