简体   繁体   中英

Why does Convert.ToInt32(Int32) exist?

There is an overload of Convert.ToInt32 that takes Int32 as the parameter. But even the documentation says that basically nothing happens and the method returns its input.

The question is why do we have such overload? Is there any purpose of it? Can anyone give me an example of using this method?

My thoughts : I think we may have it because there is an overload that takes Object. And thus we want to eliminate boxing and so on. But I'm not sure.

My ideas:

  • For code generation : Especially in .NET 2.0, a lot of code as eg typed data sets were generated. Having an overload like Convert.ToInt32(Int32) simplifies the code generator but does not hamper runtime performance, since the call is probably JITed away immediately
  • For consistency : There is an IConvertible interface in .NET since 2.0 or maybe even since 1.0 that is used by the Convert class. This interface demands methods like ToInt32, etc.

Code Generation (more details): The usual method to generate code back in .NET 2.0 times was System.CodeDOM as it provides means to reuse the same code generator for multiple languages, most prominently VB.NET and C#. In CodeDOM, you don't need to know of what type a given expression is to call a method, you can simply create a CodeMethodCallExpression given on the target object expression and the methods name. On the other hand, many cast operators such like C#s as operator are not supported by CodeDOM.

As a consequence, it is often hard to know the type of a given code expression in CodeDOM. This totally makes sense as many methods that an expression may involve are also part of the generated code and thus unknown at generation time. However, in some cases you need a particular expression converted to a given type, such as System.Int32 . I can imagine this actually happened for typed data sets, although I am not 100% sure. Because Convert.ToInt32 exists, the generator does not need to know whether a given expression is of type System.Int32 or not. When the compiler compiles the generated code, all the methods signatures are available and the compiler may figure out that the type of the expression is System.Int32 and call the appropriate overload.

On the other side, the JIT compiler will detect that the method Convert.ToInt32 will simply return its argument. But as the method is not virtual, the methods body can be inserted into the callers code instead of calling Convert.ToInt32 as the overhead of calling the method would be much higher than the method body.

Only the API designers know.

If I had to make a guess, I would guess it is for the sake of consistency - for example, when you are using reflection to dynamically create calls, it's easier if you can make the assumption that every Convert.ToX(Y) combination exists for any primitive types X and Y .

We can derive one possible answer from usages of ToInt32(Int32) in the framework classes.

Eg System.Activities.DurableInstancing.SerializationUtilities

public static byte[] CreateKeyBinaryBlob(List<CorrelationKey>correlationKeys)
{
     [...]
     Convert.ToInt32(correlationKey.BinaryData.Count)

and System.ComponentModel.Design.CollectionEditor

private void PaintArrow(Graphics g, Rectangle dropDownRect)
{
    Point point = new Point(Convert.ToInt32(dropDownRect.Left + dropDownRect.Width / 2), Convert.ToInt32(dropDownRect.Top + dropDownRect.Height / 2));

In both cases we can see that the type of the property or expression is currently Int32, but there's a reasonable expectation that /maybe/ that type might be different on different platforms, CPU architectures, future versions of the framework etc.

So my proposed answer is that it exists as a sort of future proofing of the source code, to allow it to compile without modification even when some key 'entities' (such as window X and Y coords) change type.

Common Language Runtime use internally the IConvertible interface. As the CLR base types are Boolean, SByte, Byte, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, Decimal, DateTime, Char y String, there are an Implementation for each one of them in Convert class.

But, for example, Convert.toBoolean(DateTime) always return an Exception, by design.

Here's the method description:

    //
    // Summary:
    //     Returns the specified 32-bit signed integer; no actual conversion is performed.
    //
    // Parameters:
    //   value:
    //     The 32-bit signed integer to return.
    //
    // Returns:
    //     value is returned unchanged.

Only thing I can think of is that it's a shortcut/pass-through if the input is already an int . It's likely much more efficient than if an int was passed into Convert.ToInt32(object) .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM