【问题标题】:TypeCode vs typeofTypeCode 与 typeof
【发布时间】:2017-04-25 22:45:16
【问题描述】:

如果我需要一些特定类型的代码,我可以使用typeof,例如:

private static bool IsNumericType(Type type)
{
    return type == typeof(int) || type == typeof(decimal); //etc
}

但我也可以使用枚举TypeCode

private static bool IsNumeric(TypeCode objTypeCode)
{
    return objTypeCode == TypeCode.Int16 || objTypeCode == TypeCode.Int32 || objTypeCode == TypeCode.Int64; // etc ||
}

从架构和性能的角度来看,使用TypeCode 比使用typeof 有什么好处?在哪种情况下我应该使用两者之一?

仅供参考,从值中获取 type / typeCode 的代码:

var type = value.GetType();
var typeCode =  Convert.GetTypeCode(value);

PS:这些示例被高度简化。

PS 2:如果我传递值,我也可以使用asis 等。但在这种情况下,我不喜欢发送,因为方法不需要知道值,只有它是输入。

【问题讨论】:

  • 我相当肯定以前的 sn-p 性能会更好。基于typeof() 在编译时与运行时执行的事实。它也不需要Convert.GetTypeCode() 调用。不过,您始终可以对其进行基准测试并亲自查看!
  • GetTypeCode 在 .NET 版本 1 中潜入。在那些没有泛型的黑暗厄运绝望的日子里,让 switch 语句高效返回非常重要。这在版本 2 中得到了修复。他们甚至在版本 7 中修复了 switch 语句。

标签: c# typeof typing


【解决方案1】:

TypeCode 在您遵循几种可能的路径时效果最佳,并且大部分或所有逻辑都可以通过单独检查代码来完成,因为然后switching 将非常有效,并且通常非常清晰。

在其他情况下,Object 分支内部的逻辑可能与外部一样多,因为这是大多数类型的代码,在这种情况下,首先检查代码往往没有那么有用,除非可能是这种情况被它很好地服务的也是特别经常出现的案例。

您的IsNumeric 示例是一个很好的示例,说明TypeCode 何时运行良好,如果您将其重写为一个开关,您将通过一个虚拟调用来获取代码和一个编译为相对有效跳转的开关而不是对不同可能类型的多重比较进行分支。

请注意,枚举类型与其基础数字类型具有相同的代码。这算作免费承保这些案件,还是您必须单独防范的案件,取决于您出于何种目的考虑这些类型。

【讨论】:

    【解决方案2】:

    回答前的几点说明:

    1. typeof 采用类型(不是实例)
    2. GetTypeCode 需要一个实现IConvertible 接口的实例

    因此它们是不同的。所以你需要问自己的问题是你想要实例的类型还是类型。


    这是来自 MSDN:

    在实现 IConvertible 接口的类上调用 GetTypeCode 方法以获取该类实例的类型代码。 否则,调用对象的GetType方法获取其Type对象,然后调用Type对象的GetTypeCode方法获取对象的类型码。

    因此,如果一个类型没有实现IConvertible接口,那么你需要进行2次调用:GetType,然后调用GetTypeCode。我还从GetTypeCode 的.NET 源代码中提取了代码:

    public static TypeCode GetTypeCode(Type type)
    {
        if (type == null)
            return TypeCode.Empty;
        return type.GetTypeCodeImpl();
    }
    
    protected virtual TypeCode GetTypeCodeImpl()
    {
        // System.RuntimeType overrides GetTypeCodeInternal
        // so we can assume that this is not a runtime type
    
        // this is true for EnumBuilder but not the other System.Type subclasses in BCL
        if (this != UnderlyingSystemType && UnderlyingSystemType != null)
            return Type.GetTypeCode(UnderlyingSystemType);
    
        return TypeCode.Object;
    }
    

    如您所见,那里发生了很多事情。现在没有基准测试很难说,但我很确定因为typeof 是编译时间,而且它是 C# 的原生代码,团队已经投入工作以提高效率。 typeof 的事实是:

    1. C# 原生
    2. 在编译时决定
    3. 不依赖于接口
    4. 在某些情况下不是 2 次调用
    5. 更直接

    我会选择typeof

    我一直记得这条规则:

    首先让它工作。然后,仅当您需要使其工作得更快时,才进行更改。

    【讨论】:

    • GetTypeCode 不需要实现IConvertible 接口的实例,您可以在任何类型上调用Type.GetTypeCode()
    • 看起来GetTypeCode() 扩展方法仅适用于实现IConvertible 的对象,但您可以将任何类型传递给Type.GetTypeCode() 方法。
    • 在将类型传递给Type.GetTypeCode() 时请注意:我尝试实现IConvertible 接口。但是无论我选择在该实现的GetTypeCode() 中返回什么,Type.GetTypeCode(type) 总是返回Object
    猜你喜欢
    • 2023-04-08
    • 2023-03-08
    • 1970-01-01
    • 2017-04-28
    • 2011-09-27
    • 1970-01-01
    • 1970-01-01
    • 2017-05-18
    • 2010-12-31
    相关资源
    最近更新 更多