简体   繁体   English

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

[英]What's the difference between Marshal.SizeOf(typeof(T)) and Marshal.SizeOf(default(T))?

Is there any difference in the purpose, result, and/or performance (across all types) of: (在所有类型中)的目的,结果和/或性能是否存在任何差异:

Marshal.SizeOf(typeof(T))

and

Marshal.SizeOf(default(T))

?

The first method takes a type, the second method takes an instance. 一种方法采用类型,第二种方法采用实例。 They both return the size of the associated structure. 它们都返回关联结构的大小。

The latter method calls the former. 后一种方法称为前者。 This is backed up by the source in coreclr: 这由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);
}

An important distinction is that when using reference types one of your calls will raise an exception the other wont: 一个重要的区别是,使用引用类型时,您的一个调用会引发异常,而另一个不会:

This will succeed: 这将成功:

Marshal.SizeOf(typeof(AReferenceType))

This will error (null passed to method) 这将出错(将空值传递给方法)

Marshal.SizeOf(default(AReferenceType))

Beware of reference types: Marshal.SizeOf<T> Method (T) : 当心引用类型: Marshal.SizeOf <T>方法(T)

ArgumentNullException The structure parameter is null. ArgumentNullException结构参数为null。

For a reference type, default(T) will be null , so thats not a good idea. 对于引用类型, default(T)将为null ,所以这不是一个好主意。

In the first call you pass an instance of type Type, which is a reference type. 在第一个调用中,您传递了Type类型的实例,该实例是引用类型。 Its size will be always the same as the size of all reference types. 它的大小将始终与所有引用类型的大小相同。

In the second call, however, you pass a value, which can be of : 1. A reference type, and will be the same size as in the first call. 但是,在第二个调用中,您传递的值可以是:1.引用类型,其大小将与第一个调用中的大小相同。 2. A value type, and now this can vary. 2.值类型,现在可以有所不同。 For example, .SizeOf(default(byte)) will return 1, .SizeOf(default(int)) will return 4, .SizeOf(default(long)) will return 8. 例如,.SizeOf(default(byte))将返回1,.SizeOf(default(int))将返回4,.SizeOf(default(long))将返回8。

The difference is the same as between Marshal.SizeOf(typeof(int)) , Marshal.SizeOf<int>() and Marshal.SizeOf(0) . 区别与Marshal.SizeOf(typeof(int))Marshal.SizeOf<int>()Marshal.SizeOf(0)

Internally, they all do the same: 在内部,它们都执行相同的操作:

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

     Marshal.SizeOfHelper(structure.GetType(), true) 
  • Marshal.SizeOf(Type t) just calls the same method with known type: Marshal.SizeOf(Type t)只会调用已知类型的相同方法:

     Marshal.SizeOfHelper(t, true) 
  • Marshal.SizeOf<T>() calls the previous overload: Marshal.SizeOf<T>()调用先前的重载:

     Marshal.SizeOfHelper(typeof(T)) 

As for me, I would prefer generic version whenever type is known at compile time or generic ; 对于我而言,我更喜欢泛型版本,只要在编译时知道type即可 Type overload whenever type will be known at runtime; Type过载每当类型将在运行时已知的; and object overload when you have an object, not a type. object重载,当您有一个对象,而不是一个类型。 It looks like it is what every method was designed for. 看起来这是每种方法都设计的目的。

Moreover, Marshal.SizeOf(default(T))` makes its purpose less clear and readable. 而且,Marshal.SizeOf(default(T))`使其用途不太清晰和易读。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM