== operator not working on boxed value types

  • Thread starter Thread starter Kenneth Baltrinic
  • Start date Start date
K

Kenneth Baltrinic

I have the following routine that is always throwing the error at the end.
It never returns from within the foreach loop because the if expression is
always evaluating to false apparently. This is something of a problem. The
comparison is between two objects (Handler.Data is defined as returning an
object.), but these objects are always nothing more than boxed value types
(either strings or ints or an int based enumeration). If for the sake of a
particular test where I knew all the values were ints, I recoded the
comparison to look like
if((int)Handler.Data == (int)Value)
and all worked fine. The problem is I can rely on this assumption. Any
suggestions on this issue?

protected virtual void HandleValueChange(ref object Value)
{
foreach(PSCForms.MenuHandler Handler in MenuHandlers)
if(Handler.Data == Value)
{
Handler.MenuItem.DefaultItem = true;
this.Text = Handler.MenuItem.Text.Replace("&", "");
return;
}

throw new ArgumentOutOfRangeException(
"Value", Value, "The value is not is the list of acceptable values.");
}

P.S. One more bizarre thing, if I put (Handler.Data == Value) in a watch
window and step through the routine, the window indicates that the
expression evaluates to true for the appropriate iteration, but the code
within the if block still does not run. Could this be a C# bug?

--Ken
 
Hello

With the variables of type object, the == performs a reference equality,
which is usually false unless the 2 objects actually reference to the same
object.
You should use the static method Object.Equals(object1, object2).

Best regards
Sherif
 
I am aware of how the operator works for object variables in general but I
was under the impression it would unbox boxed value types before applying a
operator. This is particularly so since the watch window did in fact return
the value I was expecting. That the watch window and code execution are out
of step is most disturbing.

What about the instance method Equals()? I just tested it and it works as
well. This is unrelated to my issue but why is there both an instance and
static method?

--Ken
 
Kenneth Baltrinic said:
I have the following routine that is always throwing the error at the end.

protected virtual void HandleValueChange(ref object Value)

Sherif has answered your main question, but I'm concerned with your use
of "ref" here - you're not changing the value of the "Value" variable,
which means that it being passed by reference is irrelevant. Is there
more code in the real method which makes it worth doing this?

See http://www.pobox.com/~skeet/csharp/parameters.html for more
information.
P.S. One more bizarre thing, if I put (Handler.Data == Value) in a watch
window and step through the routine, the window indicates that the
expression evaluates to true for the appropriate iteration, but the code
within the if block still does not run. Could this be a C# bug?

I rather suspect that the watch window uses slightly different
techniques to evaluate things, unfortunately.
 
Kenneth Baltrinic said:
I am aware of how the operator works for object variables in general but I
was under the impression it would unbox boxed value types before applying a
operator.

Why would it do that? It would have to check whether or not the
reference type was a boxed value, and make that check *every* time it
did a reference comparison. That would make it *much* slower, IMO.
What about the instance method Equals()? I just tested it and it works as
well. This is unrelated to my issue but why is there both an instance and
static method?

The static method is more convenient if the references in question
could both be null.
 
Hello

The instance version of Equals is fine, but object1.Equals(object2) will
throw a NullReferenceException if object1 is null. So if you know that
object1 should never be null then instance version is fine ( and even
better). The static version check for if the value is null, and actually
calls the instance version.

Best regards,
Sherif
 
Good point about the null exception. Its a non issue in this case. And I
do see the point about why it does not unbox. For some reason I was
thinking that the decision to unbox could be made at compile time. Duh.
Fuzzy thinking yesterday.

Regarding the person who queried about the use of the ref modifier, this is
a protected implementation. Overriding implementations may need to modify
the value though this one does not.

Again thanks for al the help.

--Ken
 
Back
Top