TypeCode 与 typeof
TypeCode vs typeof
如果我需要一些特定类型的代码,我可以使用 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:如果我传递值,我也可以使用 as
、is
等。但是在这种情况下,我不喜欢发送,因为该方法没有不需要知道值,只需要知道它的类型。
回答前的几点说明:
typeof
采用类型(不是实例)
IConvertible.GetTypeCode
需要一个实现 IConvertible
接口的实例
因此它们是不同的。所以你需要问自己的问题是你想要一个实例的类型还是一个类型。
Call the GetTypeCode
method on classes that implement the IConvertible
interface to obtain the type code for an instance of that class.
Otherwise, call an object's GetType
method to obtain its Type
object, then call the Type object's GetTypeCode
method to obtain the object's type code.
因此,如果一个类型没有实现IConvertible
接口,那么你需要进行2次调用:GetType
然后调用GetTypeCode
。我还从 .NET 源代码中提取了 GetTypeCode
:
的代码
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
的事实是:
- C# 原生
- 编译时决定
- 不依赖于接口
- 在某些情况下不是2次调用
- 更直接
我会选择 typeof
。
我一直记得这条规则:
首先让它发挥作用。然后,只有当你需要让它工作得更快时,才改变它。
TypeCode
在您遵循多个可能的路径时效果最佳,并且大部分或所有逻辑都可以通过单独检查代码来完成,因为 switch
这样做会非常有效,大体上很清楚。
在其他情况下,Object
分支内部的逻辑可能与外部的逻辑一样多,因为这是大多数类型的代码,在这种情况下,首先检查代码往往没有用除非也许它服务好的案例也是特别经常出现的案例。
您的 IsNumeric
示例是 TypeCode
何时运行良好的一个很好的示例,就像您将其重写为一个开关,您通过一个虚拟调用来获取代码和一个此类开关来应答编译成相对有效的跳转,而不是在不同可能类型的多重比较上分支。
请注意,枚举类型与其基础数字类型具有相同的代码。这算作免费涵盖这些案例,还是您必须单独防范的案例,取决于您出于何种目的如何考虑这些类型。
如果我需要一些特定类型的代码,我可以使用 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:如果我传递值,我也可以使用 as
、is
等。但是在这种情况下,我不喜欢发送,因为该方法没有不需要知道值,只需要知道它的类型。
回答前的几点说明:
typeof
采用类型(不是实例)IConvertible.GetTypeCode
需要一个实现IConvertible
接口的实例
因此它们是不同的。所以你需要问自己的问题是你想要一个实例的类型还是一个类型。
Call the
GetTypeCode
method on classes that implement theIConvertible
interface to obtain the type code for an instance of that class.
Otherwise, call an object'sGetType
method to obtain itsType
object, then call the Type object'sGetTypeCode
method to obtain the object's type code.
因此,如果一个类型没有实现IConvertible
接口,那么你需要进行2次调用:GetType
然后调用GetTypeCode
。我还从 .NET 源代码中提取了 GetTypeCode
:
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
的事实是:
- C# 原生
- 编译时决定
- 不依赖于接口
- 在某些情况下不是2次调用
- 更直接
我会选择 typeof
。
我一直记得这条规则:
首先让它发挥作用。然后,只有当你需要让它工作得更快时,才改变它。
TypeCode
在您遵循多个可能的路径时效果最佳,并且大部分或所有逻辑都可以通过单独检查代码来完成,因为 switch
这样做会非常有效,大体上很清楚。
在其他情况下,Object
分支内部的逻辑可能与外部的逻辑一样多,因为这是大多数类型的代码,在这种情况下,首先检查代码往往没有用除非也许它服务好的案例也是特别经常出现的案例。
您的 IsNumeric
示例是 TypeCode
何时运行良好的一个很好的示例,就像您将其重写为一个开关,您通过一个虚拟调用来获取代码和一个此类开关来应答编译成相对有效的跳转,而不是在不同可能类型的多重比较上分支。
请注意,枚举类型与其基础数字类型具有相同的代码。这算作免费涵盖这些案例,还是您必须单独防范的案例,取决于您出于何种目的如何考虑这些类型。