为什么 Convert.ToInt32(Int32) 存在?

Why does Convert.ToInt32(Int32) exist?

有一个 Convert.ToInt32 的重载,它以 Int32 作为参数。但即使 documentation says that basically nothing happens 和方法 returns 它的输入。

问题是为什么我们有这样的超载?有什么目的吗?谁能给我一个使用这种方法的例子吗?

我的想法:我想我们可能有它,因为有一个重载对象。因此我们想要消除拳击等等。但我不确定。

我的想法:

  • 对于代码生成:特别是在.NET 2.0中,很多代码如生成了类型数据集。像 Convert.ToInt32(Int32) 这样的重载简化了代码生成器,但不会影响运行时性能,因为调用可能会立即被 JITed 掉
  • 为了一致性:从 2.0 开始,甚至可能从 1.0 开始,.NET 中就有一个 IConvertible 接口供 Convert class 使用。此接口需要 ToInt32 等方法

代码生成(更多细节): 在 .NET 2.0 时代生成代码的常用方法是 System.CodeDOM,因为它提供了为多种语言重用相同代码生成器的方法,最突出的是 VB.NET 和 C#。在 CodeDOM 中,您不需要知道给定表达式是什么类型来调用方法,您可以简单地创建一个给定目标对象表达式和方法名称的 CodeMethodCallExpression。另一方面,CodeDOM 不支持许多转换运算符,例如 C#s as 运算符。

因此,通常很难知道 CodeDOM 中给定代码表达式的类型。这完全是有道理的,因为表达式可能涉及的许多方法也是生成代码的一部分,因此在生成时是未知的。但是,在某些情况下,您需要将特定表达式转换为给定类型,例如 System.Int32。我可以想象这实际上发生在类型化数据集上,尽管我不是 100% 确定。因为 Convert.ToInt32 存在,所以生成器不需要知道给定表达式是否属于 System.Int32 类型。当编译器编译生成的代码时,所有的方法签名都是可用的,编译器可能会发现表达式的类型是 System.Int32 并调用适当的重载。

另一方面,JIT 编译器会检测到方法 Convert.ToInt32 将简单地 return 它的参数。但由于该方法不是虚拟的,方法体可以插入到调用者代码中而不是调用 Convert.ToInt32 因为调用方法的开销会比方法体高得多。

只有 API 设计师知道。

如果我不得不猜测,我猜是为了保持一致性——例如,当您使用反射动态创建调用时,如果您可以假设每个 Convert.ToX(Y) 组合存在于任何原始类型 XY.

公共语言运行时在内部使用 IConvertible 接口。 由于 CLR 基本类型是 Boolean、SByte、Byte、Int16、UInt16、Int32、UInt32、Int64、UInt64、Single、Double、Decimal、DateTime、Char y String,因此在 Convert [=15 中对它们中的每一个都有一个实现=].

但是,例如,Convert.toBoolean(DateTime) 总是 return 一个异常,这是设计使然。

方法说明如下:

    //
    // 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.

我唯一能想到的是,如果输入已经是 int,它就是 shortcut/pass-through。它可能比将 int 传递给 Convert.ToInt32(object).

更有效

我们可以从框架 类.

中对 ToInt32(Int32) 的用法得出一个可能的答案

例如 System.Activities.DurableInstancing.SerializationUtilities

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

和 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));

在这两种情况下,我们都可以看到 属性 或表达式的类型当前为 Int32,但有一个合理的预期/可能/该类型在不同平台上可能会有所不同,CPU体系结构、框架的未来版本等

所以我建议的答案是它作为源代码的一种未来校对而存在,即使在某些关键 'entities'(例如 window X 和Y坐标)改变类型。