sizeof()與Marshal.SizeOf()的不同


在.NET中一般都是通過sizeof()或Marshal.SizeOf()來獲取數據類型的大小,來簡要地看一下它們二者有何不同。

sizeof()

sizeof()在MSDN中的介紹是,在編譯時獲得一個數據類型的確定大小,並且被指定為一個常量。如果試圖把它用在無效類型上則會出現編譯錯誤,見CS0233

也就意味着在運行階段它是沒有開銷的。

例子

1 sizeof(int)

編譯成IL則為:

ldc.i4.4 

 

Marshal.SizeOf()

在System.Runtime.InteropServices.Marshal.SizeOf(),MSDN介紹是,總是在運行時計算結構化數據類型的大小。

這就是說,像裝箱或者計算大小的開銷在該方法被調用時。

例子

Marshal.SizeOf<int>()

編譯成IL則為: 

call        System.Runtime.InteropServices.Marshal.SizeOf<Int32>

 

一窺究竟

我們可以看看源碼 (referencesource)

 1 //====================================================================
 2 // SizeOf()
 3 //====================================================================
 4 [ResourceExposure(ResourceScope.None)]
 5 [System.Runtime.InteropServices.ComVisible(true)]
 6 public static int SizeOf(Object structure)
 7 {
 8     if (structure == null)
 9 throw new ArgumentNullException("structure");
10     // we never had a check for generics here
11     Contract.EndContractBlock();
12  
13     return SizeOfHelper(structure.GetType(), true);
14 }
15  
16 public static int SizeOf<T>(T structure)
17 {
18     return SizeOf((object)structure);
19 }
20  
21 [ResourceExposure(ResourceScope.None)]
22 [Pure]
23 public static int SizeOf(Type t)
24 {
25     if (t == null)
26 throw new ArgumentNullException("t");
27     if (!(t is RuntimeType))
28 throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), "t");
29     if (t.IsGenericType)
30 throw new ArgumentException(Environment.GetResourceString("Argument_NeedNonGenericType"), "t");
31     Contract.EndContractBlock();
32  
33     return SizeOfHelper(t, true);
34 }
35  
36 public static int SizeOf<T>()
37 {
38     return SizeOf(typeof(T));
39 }
40  
41 [ResourceExposure(ResourceScope.None)]
42 [MethodImplAttribute(MethodImplOptions.InternalCall)]
43 internal static extern int SizeOfHelper(Type t, bool throwIfNotMarshalable);

從上面可以看出這個Marshal.SizeOf()方法依賴SizeOfHelper這個外部方法的引用,如果數據類型有提供則在外部執行計算。如果是結構體裝箱為對象,則把該對象當參數傳入。

注意事項

如下Marshal.SizeOf<T>() 與sizeof(T)的一些類型,計算出大小的結果

1 Marshal.SizeOf<Boolean>(): 4
2 sizeof(Boolean): 1
3 Marshal.SizeOf<Char>(): 1
4 sizeof(Char): 2

看這些相同類型下,在.Net中被封送處理成非托管的數據類型時,原托管類型2個字節的Char計算成了Windows系統類型中的1個字節的SBYTE,而托管類型1個字節的Boolean計算成了Windows系統類型中的4個字節的BOOL。

(原文引自:sizeof() vs Marshal.SizeOf()


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM