Ser*_*694 32 .net c# cil visual-studio
首先,在实际问题之前的一个小免责声明:
我知道关于
sizeof
运算符和Marshal.SizeOf<T>
方法之间的区别有很多关闭/重复的问题,我确实理解了两者之间的区别.这里我说的SizeOf<T>
是新Unsafe
课程中的方法
所以,我不确定我是否理解这两个操作之间的实际区别,特别是在结构/类上使用该方法时是否存在特定的差异.
该sizeof
运营商需要一个类型名称,返回的数量管理字节它应该占用分配时(即一个Int32
将返回4,例如).
Unsafe.SizeOf<T>
另一方面,该方法在IL中实现,就像类中的所有其他方法一样Unsafe
,并且在这里看代码是它的作用:
.method public hidebysig static int32 SizeOf<T>() cil managed aggressiveinlining
{
.custom instance void System.Runtime.Versioning.NonVersionableAttribute::.ctor() = ( 01 00 00 00 )
.maxstack 1
sizeof !!T
ret
}
Run Code Online (Sandbox Code Playgroud)
现在,如果我没有错,代码只是调用sizeof !!T
wich与sizeof(T)
调用sizeof
带有类型名称的运算符相同T
,那么它们中的两个是否完全等价?
另外,我看到该方法也在NonVersionableAttribute
第一行中分配了一个无用的对象(the ),所以这不会导致少量的内存被堆分配吗?
我的问题是:
是否可以肯定地说这两种方法是完全等价的,因此使用经典
sizeof
算子更好,因为这也避免了在SizeOf<T>
方法中分配该属性?这被SizeOf<T>
添加到方法Unsafe
类只是为了方便,在这一点?
Evk*_*Evk 24
虽然这种方法确实只使用sizeof
IL指令 - 但与常规sizeof
运算符存在差异,因为此运算符不能应用于任意类型:
用于获取非托管类型的字节大小.非托管类型包括下表中列出的内置类型,以及以下内容:
枚举类型
指针类型
用户定义的结构,不包含任何作为引用类型的字段或属性
如果你试着写模拟Unsafe.SizeOf
- 它将无法工作:
public static int SizeOf<T>()
{
// nope, will not compile
return sizeof(T);
}
Run Code Online (Sandbox Code Playgroud)
因此Unsafe.SizeOf
提升了sizeof
运算符的限制,允许您使用sizeof
任意类型的IL 指令(包括将返回引用大小的引用类型).
至于你在IL中看到的属性构造 - 这并不意味着将为每个调用实例化属性 - 这只是用于将属性与各种成员相关联的IL语法(在本例中为方法).
例子:
public struct Test {
public int Int1;
}
static void Main() {
// works
var s1 = Unsafe.SizeOf<Test>();
// doesn't work, need to mark method with "unsafe"
var s2 = sizeof(Test);
}
Run Code Online (Sandbox Code Playgroud)
另一个例子:
public struct Test {
public int Int1;
public string String1;
}
static unsafe void Main() {
// works, return 16 in 64bit process - 4 for int, 4 for padding, because
// alignment of the type is the size of its largest element, which is 8
// and 8 for string
var s1 = Unsafe.SizeOf<Test>();
// doesn't work even with unsafe,
// cannot take size of variable of managed type "Test"
// because Test contains field of reference type (string)
var s2 = sizeof(Test);
}
Run Code Online (Sandbox Code Playgroud)