2012-07-04 27 views
6

Tôi đã thử nghiệm tác động của việc gọi một thành viên ảo trong một nhà xây dựng, và phát hiện ra rằng khi gọi thành viên đó, ngoại lệ kết quả được bao bọc trong một TargetInvocationException.Các thành viên ảo có được gọi qua phản xạ (trong hoàn cảnh bình thường) không?

Theo docs này là:

Trường hợp ngoại lệ được ném bằng phương pháp gọi thông qua phản ánh

Tuy nhiên tôi không biết về bất kỳ invokations thông qua phản ánh. Vì vậy, điều này có nghĩa là các thành viên ảo có nghĩa là luôn luôn được gọi là thông qua sự phản ánh? Nếu không phải lý do tại sao trong trường hợp này?

Mã:

class ClassA 
    { 
     public ClassA() 
     { 
      SplitTheWords(); 
     } 

     public virtual void SplitTheWords() 
     { 
      //I've been overidden 
     } 
    } 

class ClassB : ClassA 
    { 
     private readonly String _output; 

     public ClassB() 
     { 
      _output = "Constructor has occured"; 
     } 

     public override void SplitTheWords() 
     { 
      String[] something = _output.Split(new[]{' '}); //TargetInvocationException! 
     } 
    } 

Trả lời

5

Không, phương pháp ảo được gọi qua virtual dispatch.

Phản ánh không được sử dụng tại đây. Và cũng không phải là cho bất kỳ cuộc gọi phương thức ảo nào. Tôi tin rằng tài liệu cho trường hợp ngoại lệ là hơi gây hiểu lầm trong trường hợp ngoại lệ của loại này là được ném bởi các phương thức được gọi thông qua phản ánh, tuy nhiên không phải độc quyền như vậy.

Nếu bất kỳ ai tò mò là tại sao mã trong câu hỏi đưa ra một ngoại lệ, đó là do thứ tự các nhà thầu được thực thi. Các nhà xây dựng ClassB là giống như:

public ClassB() : base() 
{ 
    _output = "Constructor has occured"; 
} 

Lưu ý các cuộc gọi đến base(), đây gọi là nhà xây dựng cơ sở trước khi các nhà xây dựng ClassB được điều hành và do đó, trước _output được gán. Phương thức ảo SplitTheWords được gọi trong hàm tạo cơ sở, giải quyết thành ClassB.SplitTheWords. Phương pháp này cố gắng sử dụng _output, do đó lỗi.

Để biết chi tiết hơn tại sao các phương pháp ảo không nên được gọi từ các nhà xây dựng this SO question có một số thông tin hữu ích. Eric Lippert cũng có một bài đăng trên blog rất hay về lý do tại sao đây là trường hợp here.

+1

+1 cho "hơi gây nhầm lẫn", đó là điều gây nhầm lẫn sâu sắc đối với tài liệu để nói. Người ta có thể viết một ứng dụng giao diện điều khiển mà không có gì ngoại trừ 'ném mới TargetInvocationException();' - nơi sẽ là sự phản ánh sau đó? – AakashM

+0

Tôi hiểu _why_ thành viên ảo không nên được gọi từ các nhà thầu, đây là những gì khiến tôi thử cách này –

+0

@ m.edmondson Xin lỗi, tôi hiểu điều này từ dòng của bạn về 'Tôi đã thử nghiệm tác động của ...', tôi không có ý định trả lời của tôi để được condescending (nhưng tôi nghĩ rằng nó bây giờ có thể được), tôi chỉ đơn thuần bao gồm các đoạn văn cuối cho đầy đủ cho những người khác nhìn thấy câu trả lời này. Tôi sẽ cố gắng nói lại. –

0

có thành viên ảo gọi thông qua phản ánh (trong trường hợp bình thường)?

NO.

Cũng không phải từ một nhà xây dựng, vì vậy một điều gì đó khác đang diễn ra. Nó sẽ giúp xem mã gọi mã bạn đã hiển thị và theo dõi ngăn xếp từ ngoại lệ.

Các vấn đề liên quan