如何確定是否需要使用「Call」或「Callvirt」調用方法?.NET CIL Call或CallVirt?
6
A
回答
4
您可以遵循這些簡單的規則逐一確定你應該使用:
- 是方法
static
?然後使用call
。 - 是您在值類型上調用的類型?然後使用
call
。 (這不適用,如果該值盒裝 - 那麼你實際上是在調用上object
或一些接口,而這些都是引用類型。) - 是要調用聲明
virtual
或abstract
的方法?然後使用callvirt
。 - 您是否正在通過接口引用調用該方法?然後使用
callvirt
。 - 您調用的方法是否被聲明爲
override
,但方法和聲明類型均未聲明sealed
?然後使用callvirt
。
在其他情況下,沒有虛擬調度是必需的,所以你可以使用call
- 但你應該使用callvirt
。原因如下:
在非虛擬方法上使用callvirt
相當於call
,除非第一個參數爲空。在這種情況下,callvirt
將立即拋出NullReferenceException
,而call
不會。這是有道理的,因爲callvirt
旨在用於需要虛擬方法調度的情況,並且如果沒有用於執行vtable查找的對象,則不能執行虛擬方法調度。
請注意,即使不需要vtable查找,如果第一個參數爲空,callvirt
仍然會引發異常!
考慮該信息,使用callvirt
對引用類型的所有非靜態方法調用(如C#編譯器一樣)可以是優選的,因爲它會立即導致一個NullReferenceException
在調用位置,而不是一段時間後,當this
被使用(顯式或隱式地)在方法內部。
6
默認情況下,除靜態或值類型調用外,C#編譯器始終對callvirt使用callvirt。這會導致'this'(arg0)參數的隱式空檢查。你並沒有嚴格遵守這個約定,但是任何引用類型的虛擬方法肯定會需要callvirt。
+1
除密封類上的虛擬方法外。 – 2015-03-11 21:09:20
0
如果您在虛擬方法的動態方法中使用調用,則運行時將引發安全異常。
相關問題
- 1. .NET CIL代碼大小
- 2. IL Callvirt等價?
- 3. Ajax Call + ASP.NET + .NET Remoting
- 4. NET CIL操作評估堆棧
- 5. .NET中CIL知識的優點
- 6. callvirt如何在引擎蓋下工作?
- 7. CIL ANTLR語法?
- 8. 以編程方式訪問.NET類型的CIL
- 9. 在WP7中阻止CALL或SMS
- 10. 是否有類似.NET的.call命令?
- 11. 錯誤在CIL中。未找到方法:'?'
- 12. 寫入CIL
- 13. 尋找一種在運行時操作.Net CIL的方法
- 14. 參數如何在CIL函數調用中傳遞?
- 15. 在CIL(MSIL)中的Stringbuilder
- 16. 在CIL中做什麼「auto」,「ansi」和「cil managed」?
- 17. Frama-C:在Cil謂詞中替換Cil術語
- 18. CIL中的nop是什麼?
- 19. .NET 4.0的CIL(公共中間語言)已更改嗎?
- 20. 如何使用.NET CIL JMP的操作碼
- 21. .Net CIL jmp操作碼和通用方法
- 22. 在CIL中分支
- 23. 優化CIL輸出
- 24. jquery post call call not works
- 25. CIL指令「isinst <valuetype>」
- 26. 瞭解特定的CIL/CLR優化
- 27. .net或.net MVC?
- 28. 哪些語言編譯成CIL/MSIL
- 29. Call類
- 30. call javascript
這與C#有什麼關係? – SLaks 2010-11-17 23:44:59