检查对象是否为值类型的最有效方法

sma*_*man 42 .net c# performance value-type

警告:此代码告诉,请参阅安东尼的评论

哪个更快?

1.

  public bool IsValueType<T>(T obj){
       return obj is ValueType;
  }
Run Code Online (Sandbox Code Playgroud)

2.

  public bool IsValueType<T>(T obj){
       return obj == null ? false : obj.GetType().IsValueType;
  } 
Run Code Online (Sandbox Code Playgroud)

3.

  public bool IsValueType<T>(T obj){
       return default(T) != null;
  }
Run Code Online (Sandbox Code Playgroud)

还有别的

Mar*_*ell 90

您并没有真正测试对象 - 您想测试类型.要调用它们,调用者必须知道类型,但是...... meh.鉴于签名<T>(T obj),唯一合理的答案是:

public bool IsValueType<T>() {
    return typeof(T).IsValueType;
}
Run Code Online (Sandbox Code Playgroud)

或者如果我们想要使用示例对象进行类型推断:

public bool IsValueType<T>(T obj) {
    return typeof(T).IsValueType;
}
Run Code Online (Sandbox Code Playgroud)

这不需要拳击(GetType()拳击),并没有问题Nullable<T>.一个更有趣的案例是你通过时object......

 public bool IsValueType(object obj);
Run Code Online (Sandbox Code Playgroud)

在这里,我们已经遇到了大量问题null,因为它可能是一个空Nullable<T>(结构)或类.但合理的尝试是:

public bool IsValueType(object obj) {
    return obj != null && obj.GetType().IsValueType;
}
Run Code Online (Sandbox Code Playgroud)

但请注意,对于空Nullable<T>s ,它是不正确的(并且是不可修复的).在这里担心拳击变得毫无意义,因为我们已经装箱了.

  • 有没有办法绕过`IsValueType`属性?我正在使用.NET DNX,它不支持此属性. (4认同)
  • @Shimmy - 在OP的代码中 - `if(default(T)!= null)`应该有效. (2认同)
  • 在DNX/.NET Core中,你可以这样做`typeof(your_type).GetTypeInfo().IsValueType`. (2认同)

Jus*_*ner 7

我的第一个答案是写一个简单的测试并自己找出答案.

我的第二个答案(当然没有任何测试)将是选项1.这是最简单的检查.第二种方法涉及两个单独的检查,而第三种方法涉及创建类型的默认实例.

您还应该考虑可读性.该框架已经使您能够在代码中包含以下内容:

if(someObj is ValueType)
{
    // Do some work
}
Run Code Online (Sandbox Code Playgroud)

为什么甚至打扰创建一个简单地将上述语句转换为的方法(假设您使方法成为静态并允许编译器推断泛型类型):

if(IsValueType(someObj))
{
    // Do some work
}
Run Code Online (Sandbox Code Playgroud)