Why can I convert to an int safely but not cast to an int?

Why does this work:

ComboBox cb = sender as ComboBox;
int validSelection = Convert.ToInt32(cb.Tag);
if (cb.SelectedIndex != validSelection) {
    cb.SelectedIndex = validSelection;
}

...but this:

ComboBox cb = sender as ComboBox;
int validSelection = (int)cb.Tag; // <-- fails
if (cb.SelectedIndex != validSelection) {
    cb.SelectedIndex = validSelection;
}

...errors out with "Object not set to a reference of an object"?

Upvotes: 3

Views: 400

Answers (6)

Thomas Levesque
Thomas Levesque

Reputation: 292355

Boxed value types can only be unboxed to their actual type, so if the value of Tag is not actually an int, the cast from object fails. Furthermore, if the value of Tag is null, the cast fails because a value type can't be null.

On the other hand, when you use Convert.ToInt32, the method takes whatever steps are necessary to convert the value to Int32:

  • if it's a string, parse it;
  • if it's an Int64, unbox it to Int64, then convert it to Int32;
  • if it's null, return 0
  • etc

Upvotes: 4

Ed Swangren
Ed Swangren

Reputation: 124632

A cast says: "Interpret the bits in memory that represent this thing as a [whatever] (int in this case.)

A conversion says: "Look, this thing is actually something very different in memory, but you know how to turn it into what I want, so please do so and return the result".

Upvotes: 1

ken2k
ken2k

Reputation: 48975

1) Convert.ToInt32(null) always returns 0, as said in the documentation

2) You cannot cast a null to a int, as int represents a number. Nullable int (int?) allow null values.

Upvotes: 7

Guvante
Guvante

Reputation: 19203

The former requires that Tag have an IConvertable that supports to ToInt32 method. The latter requires that Tag be an int.

Upvotes: 3

Eric J.
Eric J.

Reputation: 150108

Convert has a number of overloads that allow it to attempt the conversion from a wide range of data types, e.g. Convert.ToInt32(string)

Converts the specified string representation of a number to an equivalent 32-bit signed integer.

Your tag is presumably of a type (e.g. string) that Convert can handle.

Upvotes: 1

Fr&#233;d&#233;ric Hamidi
Fr&#233;d&#233;ric Hamidi

Reputation: 262919

That's because a conversion is not the same thing as a cast.

cb.Tag is probably a string, not an int, and one is not directly convertible to the other. Convert.ToInt32() actually parses the string and creates a new int with the converted value.

Casts only try to interpret an instance of a type as an instance of another type.

Upvotes: 13

Related Questions