Marshal.SizeOf(typeof(T))和Marshal.SizeOf(default(T))有什么区别?

  • 本文关键字:Marshal SizeOf 区别 typeof default c#
  • 更新时间 :
  • 英文 :


以下各项的目的、结果和/或性能(在所有类型中(是否有任何差异:

Marshal.SizeOf(typeof(T))

Marshal.SizeOf(default(T))

第一种方法采用类型,第二种方法采用实例。它们都返回关联结构的大小。

后一种方法调用前一种方法。这由 coreclr 中的源代码备份:

public static int SizeOf(Object structure)
{
if (structure == null)
throw new ArgumentNullException(nameof(structure));
// we never had a check for generics here
Contract.EndContractBlock();
return SizeOfHelper(structure.GetType(), true);
}
public static int SizeOf(Type t)
{
if (t == null)
throw new ArgumentNullException(nameof(t));
if (!(t is RuntimeType))
throw new ArgumentException(SR.Argument_MustBeRuntimeType, nameof(t));
if (t.IsGenericType)
throw new ArgumentException(SR.Argument_NeedNonGenericType, nameof(t));
Contract.EndContractBlock();
return SizeOfHelper(t, true);
}

一个重要的区别是,当使用引用类型时,其中一个调用将引发另一个调用不会的异常:

这将成功:

Marshal.SizeOf(typeof(AReferenceType))

这将错误(null 传递给方法(

Marshal.SizeOf(default(AReferenceType))

注意引用类型:Marshal.SizeOf方法 (T(:

ArgumentNullException 结构参数为空。

对于引用类型,default(T)将是null,所以这不是一个好主意。

在第一次调用中,传递类型为 Type 的实例,该实例是引用类型。 其大小将始终与所有引用类型的大小相同。

但是,在第二次调用中,传递一个值,该值可以是: 1. 引用类型,大小与第一次调用中的大小相同。 2.值类型,现在这可能会有所不同。 例如。大小(默认值(字节(( 将返回 1, .SizeOf(default(int(( 将返回 4, .SizeOf(default(long(( 将返回 8。

区别与Marshal.SizeOf(typeof(int))Marshal.SizeOf<int>()Marshal.SizeOf(0)之间的区别相同。

在内部,它们都做同样的事情:

  • Marshal.SizeOf(object structure)在运行时获取对象的类型:

    Marshal.SizeOfHelper(structure.GetType(), true)
    
  • Marshal.SizeOf(Type t)只是调用具有已知类型的相同方法:

    Marshal.SizeOfHelper(t, true)
    
  • Marshal.SizeOf<T>()调用上一个重载:

    Marshal.SizeOfHelper(typeof(T))
    

至于我,只要在编译时知道类型或泛型,我更喜欢通用版本;Type运行时已知类型时重载;并且object当您有一个对象而不是一个类型时,重载。看起来这就是每种方法的设计目的。

此外,Marshal.SizeOf(default(T((' 使其目的不太清晰和可读。

最新更新