Lý do mã của bạn trả về phương thức nil
là loại đối tượng không chứa phương thức có tên SomeHelper
. Kiểu chứa phương thức đó là kiểu trình trợ giúp.
Vì vậy, bạn có thể viết này sẽ trả về một phương pháp phi nil:
obj:=TSampleClass.Create;
rtype:=ctx.GetType(TypeInfo(TSampleClassHelper));
rmethod:=rtype.GetMethod('SomeHelper');
Tất nhiên, bạn ngay lập tức sẽ thấy vấn đề đầu tiên, cụ thể là việc sử dụng một loại thời gian biên dịch chỉ định, TSampleClassHelper
. Chúng tôi có thể sử dụng RTTI để khám phá TSampleClassHelper
tại thời gian chạy dựa trên loại cá thể không? Không, chúng tôi không thể, như tôi sẽ giải thích dưới đây.
Thậm chí nếu chúng tôi đặt nó sang một bên, theo như tôi thấy, không có cách nào để gọi phương thức bằng RTTI. Nếu bạn gọi rmethod.Invoke(obj, [])
thì mã trong số TRttiInstanceMethodEx.DispatchInvoke
chặn một nỗ lực gọi phương thức trợ giúp. Nó chặn nó bởi vì nó quyết định rằng kiểu cá thể không tương thích với lớp của phương thức. Mã thích hợp là:
if (cls <> nil) and not cls.InheritsFrom(TRttiInstanceType(Parent).MetaclassType) then
raise EInvalidCast.CreateRes(@SInvalidCast);
Vâng, bạn có thể lấy địa chỉ mã của phương pháp helper với rmethod.CodeAddress
nhưng bạn sẽ cần phải tìm một số cách khác để gọi phương thức đó. Thật dễ dàng để đưa nó vào một phương thức có chữ ký thích hợp và gọi nó. Nhưng tại sao phải bận tâm với rmethod.CodeAddress
trong mọi trường hợp? Tại sao không sử dụng TSomeHelperClass.SomeMethod
và cắt RTTI ra khỏi vòng lặp?
Thảo luận
độ phân giải Helper được thực hiện tĩnh dựa trên helper hoạt động tại thời điểm biên dịch. Khi bạn cố gắng gọi phương thức trợ giúp bằng RTTI, không có trợ giúp hoạt động. Từ lâu bạn đã hoàn thành việc biên dịch. Vì vậy, bạn phải quyết định lớp trợ giúp nào để sử dụng. Tại thời điểm đó, bạn không cần RTTI.
Vấn đề cơ bản ở đây là độ phân giải phương thức trợ giúp lớp về cơ bản là một quá trình tĩnh được thực hiện bằng ngữ cảnh của trình biên dịch. Vì không có ngữ cảnh trình biên dịch trong thời gian chạy, nên không thể thực hiện độ phân giải phương thức trình trợ giúp lớp bằng RTTI.
Đối với cái nhìn sâu sắc hơn vào này có một chi của Allen Bauer của câu trả lời ở đây: Find all Class Helpers in Delphi at runtime using RTTI?
tôi nhìn thấy, nhưng trong mã thực tế cuộc sống của tôi, tôi đang thử nghiệm cho 'SomeMethod' chống lại bất kỳ đối tượng tùy ý. Tôi không biết nếu đối tượng có phương pháp được xác định thông qua một người trợ giúp hay không.Vì vậy, tôi đoán nó sẽ không làm việc cho 'SomeMethod' được xác định thông qua một trợ giúp lớp. Oh well. –