Marshal.SizeOf(typeof(T))和Marshal.SizeOf(默认值(T))之间的区别是什么?

时间:2017-07-31 09:29:07

标签: c#

目的,结果和/或表现(所有类型)是否有任何差异:

Marshal.SizeOf(typeof(T))

Marshal.SizeOf(default(T))

4 个答案:

答案 0 :(得分:6)

第一个method采用一种类型,第二个method采用一个实例。它们都返回相关结构的大小。

后一种方法称前者。这由coreclr中的source支持:

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

答案 1 :(得分:4)

谨防参考类型:Marshal.SizeOf<T> Method (T)

  

ArgumentNullException结构参数为null。

对于参考类型,default(T)将为null,因此这不是一个好主意。

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

差异与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(默认(T))`使其目的不那么清晰和可读。