Any idea why this happen?
Because that’s the documented behaviour? Whether it’s Convert.ToInt32(object) or Convert.ToInt32(string), the documentation states quite clearly:
(Under return value)
A 32-bit signed integer that is equivalent to the number in value, or 0 (zero) if value is null.
or
A 32-bit signed integer equivalent to value, or zero if value is null.
As always, if reality doesn’t match expectations, the first thing you should do is check whether your expectations match the documented behaviour.
Personally I don’t fully buy the “compatibility with VB6” argument shown by Gavin. I realize it comes from Microsoft, and it may well be the genuine reason why it behaves that way – but I don’t think it’s a good reason to behave that way. There are plenty of VB-specific conversion methods – so if the framework designers genuinely thought that returning zero was a non-ideal result, they should have done whatever they thought best, and provided a VB6 compatible conversion for use by VB6 programmers.
Obviously once the behavior was defined in .NET 1.0, it couldn’t be changed for later versions – but that’s not the same as saying it had to behave the same way as VB6.