Có đúng là một phương thức thể hiện có thể được gọi trên tham chiếu null trong IL ..? Có ví dụ nào để thể hiện điều này không?Phương pháp gọi hàm trên tham chiếu null trong IL
Trả lời
Có, điều này là có thể, miễn là phương pháp không sử dụng this
vì CLR không thực hiện kiểm tra trống cho các hướng dẫn call
.
Bạn sẽ phải sửa đổi IL bằng tay vì trình biên dịch C# hầu như luôn tạo ra một hướng dẫn callvirt
.
Xem bài đăng blog để biết chi tiết và một ví dụ:
mẫu
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 18 (0x12)
.maxstack 1
.locals init ([0] class SomeClass o, [1] string hello)
IL_0000: nop
IL_0001: ldnull
IL_0002: stloc.0
IL_0003: ldloc.0
IL_0004: call instance string SomeClass::GetHello()
IL_0009: stloc.1
IL_000a: ldloc.1
IL_000b: call void [mscorlib]System.Console::WriteLine(string)
IL_0010: nop
IL_0011: ret
}
Trong thực tế, lý do mà các biên dịch C# phát ra callvirt
ngay cả trong trường hợp lệnh đơn giản call
sẽ là đủ để ngăn chặn các phương thức thể hiện gọi trên tham chiếu null. Với hành vi này của người dùng trình biên dịch sẽ nhận được một NullReferenceException
vì vậy tình huống kỳ lạ của việc gọi một phương thức trên một con trỏ null là tránh được. Eric Gunnerson đã giải thích điều này trong một bài đăng trên blog một thời gian trước đây: Why does C# always use callvirt?Gishu cũng có một lời giải thích thú vị trong một số related question.
Xem blog entry của tôi để biết thông tin.
IL code mẫu:
.class Program
{
.method static void Main(string[] args)
{
.entrypoint
.locals init ([0] class Program p)
ldloc.0 // but wait, it's still null!
call instance void Program::Awesome()
ret
}
.method instance void Awesome()
{
ldstr "Awesome!"
call void [mscorlib]System.Console::WriteLine(string)
ret
}
.method public specialname rtspecialname instance void .ctor()
{
ldarg.0
call instance void [mscorlib]System.Object::.ctor()
ret
}
}
Các CLR không đòi hỏi nó, nó là một chi tiết thực hiện của ngôn ngữ. C# và VB.NET thực hiện kiểm tra. C++/CLI là một ngôn ngữ được quản lý đáng chú ý cho phép nó. Miễn là phương thức cá thể không tham chiếu bất kỳ thành viên lớp nào thì không có gì sai. Nếu có, NullReferenceException sẽ được nâng lên như bình thường, chỉ đơn thuần là cho bạn một thời gian khó khăn tìm ra lý do tại sao.
#include "stdafx.h"
using namespace System;
ref class Test {
public:
void Run() {
Console::WriteLine("no problem");
}
};
int main(array<System::String ^> ^args)
{
Test^ obj = nullptr;
obj->Run();
return 0;
}
- 1. Phương pháp gọi trên tham chiếu null trong ngữ cảnh của mệnh đề đang sử dụng là OK?
- 2. Tạo IL cho đệ quy phương pháp
- 3. phát IL để gọi một hàm Math
- 4. Tìm Tham chiếu đến Lớp & Phương pháp
- 5. Null-an toàn Phương pháp gọi Java7
- 6. Tạo tham chiếu null
- 7. Gọi phương pháp hoặc phương pháp trực tiếp với tham số/biến/tham số trong EL
- 8. WPF Kiểm soát tham chiếu null trong InitializeComponent
- 9. Chỉ định tham chiếu theo dereferencing con trỏ NULL
- 10. Tại sao biên dịch C# gọi phương thức sản để gọi phương thức BaseClass trong IL
- 11. Phương pháp gọi trên loại chung?
- 12. Phương pháp kế thừa được trả về kiểu tham chiếu
- 13. Tại sao ném ngoại lệ trong kết quả của hàm tạo trong tham chiếu null?
- 14. gọi phương pháp khác từ phương pháp chính trong java
- 15. Ngoại lệ tham chiếu Null trong biểu thức LINQ động
- 16. C# Phương pháp động - IL vs cây biểu hiện
- 17. java null sao chép tham chiếu
- 18. Không thể tìm thấy phương pháp XXX, được tham chiếu từ phương pháp YYY
- 19. Phương pháp gọi trên lớp được bao gồm trong Ruby
- 20. Cách kiểm tra null trong các tham chiếu lồng nhau
- 21. Gọi phương thức với tham số tùy chọn thông qua phản chiếu
- 22. std :: for_each, gọi hàm thành viên với tham số tham chiếu
- 23. xóa tham chiếu null khỏi HashSet
- 24. Các loại tham chiếu không thể null
- 25. UIViewController.View.Window là null trong phương pháp viewDidLoad
- 26. Tham chiếu "này" từ trong một cuộc gọi lại javascript
- 27. C# khóa trên tham chiếu được chuyển đến phương pháp - thực hành không tốt?
- 28. undefined tham chiếu đến một hàm tĩnh
- 29. Phương pháp gọi trong JPA
- 30. Tại sao không có "tham chiếu NULL" trong C++?
Chắc chắn điều này là không thể - bạn sẽ thực hiện phương pháp nào đối với trường hợp nào? –
@Adam: rất có thể với một chút tin tặc IL. Mã này vẫn có thể xác minh 100%, nhưng trình biên dịch C# sẽ không bao giờ phát ra mã như vậy. – leppie
Đủ công bằng, làm thế nào nó nhận được từ tham chiếu null và chuyển hướng đến đúng cá thể trong bộ nhớ? Ví dụ: nếu phương thức sửa đổi trạng thái nội bộ. –