目的,结果和/或表现(所有类型)是否有任何差异:
Marshal.SizeOf(typeof(T))
和
Marshal.SizeOf(default(T))
答案 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))`使其目的不那么清晰和可读。