2012-06-22 38 views
8

Tôi sẽ tưởng tượng điều này có thể sử dụng Reflection.Emit,Có thể thêm phương thức vào một lớp EXISTING khi chạy không? tại sao hay tại sao không?

nhưng a similar question on SO chỉ trả lời cách tạo lớp/phương pháp động, chứ không phải cách cập nhật lớp hiện có.

Trong một mạch tương tự, có thể xóa các phương thức/lớp khi chạy không? Nếu vậy, tôi cho rằng người ta chỉ có thể xóa các lớp, và thêm nó trở lại với phương pháp cũ của nó cộng với cái mới.

Xin cảm ơn trước.

P.S. Tôi không có ý định sử dụng cho điều này, nó chỉ là vấn đề tò mò.

+4

Đây là ví dụ hoàn hảo về lý do tại sao các câu hỏi SO chỉ chứa một câu hỏi cho mỗi bài đăng. Marc và Henk từng trả lời một câu hỏi riêng mà bạn hỏi, và cả hai đều là câu trả lời đúng, đúng. Bạn chọn cái nào dưới dạng ** quyền ** và chấp nhận? Hãy giới hạn bản thân cho một câu hỏi ** ** duy nhất trên mỗi bài đăng để tránh tình huống này, nơi một trong những người trả lời nhận được phần thưởng và người kia thì không, mặc dù cả hai câu trả lời đều tốt, chính xác và trả lời câu hỏi của bạn. –

+0

Ok. Tôi sẽ cố nhớ điều đó trong tương lai. nguyên tắc một mục đích cho các câu hỏi thay vì các phương thức/đối tượng.Bây giờ hành động đó đã được thực hiện mặc dù, tôi có lẽ không nên thay đổi nó. – user420667

Trả lời

26

Trong C#/.NET thông thường, câu trả lời là "không" đơn giản. Nhất bạn có thể làm là viết DynamicMethod có thể hành xử như một phương thức thuộc loại đó (truy cập vào các trường riêng tư v.v.), nhưng nó sẽ không bao giờ có trên API - bạn chỉ cần kết thúc với một đại biểu.

Nếu bạn sử dụng dynamic, bạn có thể thực hiện khá nhiều thứ mình muốn. Bạn có thể mô phỏng điều đó với ExpandoObject bằng cách đính kèm đại biểu thay cho phương pháp, nhưng trên loại động tùy chỉnh, bạn có thể thực hiện mọi thứ - nhưng điều này chỉ ảnh hưởng đến người gọi sử dụng API dynamic. Đối với một cơ bản ExpandoObject dụ:

dynamic obj = new ExpandoObject(); 
Func<int, int> func = x => 2*x; 
obj.Foo = func; 
int i = obj.Foo(123); // now you see it 
obj.Foo = null; // now you don't 

cho thuộc tính và các sự kiện (không phương pháp), bạn có thể sử dụng phương pháp System.ComponentModel để thay đổi những gì xuất hiện trong thời gian chạy, nhưng điều đó chỉ tác động đến những người gọi người có thể truy cập thông qua System.ComponentModel, có nghĩa là chủ yếu là: ràng buộc dữ liệu UI. Đây là cách DataTable đại diện cho các cột dưới dạng thuộc tính giả (quên về "tập dữ liệu đã nhập" cho thời điểm này - nó hoạt động mà không có các thuộc tính đó).

Để hoàn thành, tôi cũng nên đề cập đến phương thức mở rộng. Đó là một thủ thuật biên dịch, không phải là một thủ thuật thời gian chạy - nhưng kinda cho phép bạn thêm các phương thức vào một kiểu hiện có - cho các giá trị nhỏ của "thêm".

Một mẹo cuối cùng, thường được sử dụng bởi ORM, vv - là động phân lớp loại và cung cấp chức năng bổ sung trong lớp con. Ví dụ: ghi đè thuộc tính để chặn chúng (tải chậm, v.v.).

+0

haha, "cho các giá trị nhỏ thêm". Tôi đoán rằng có nghĩa là cho các phương pháp tĩnh sau đó: -P. – user420667

+0

@ user420667 không, thực sự tôi có nghĩa là "chúng không thực sự là phương pháp trên loại". –

+0

phản hồi tuyệt vời. Bất kỳ ý tưởng về lý do tại sao mặc dù? Nó sẽ phá vỡ một số loại phát triển chính/khó thực hiện? – user420667

3

có thể xóa phương pháp/lớp học khi chạy không?

Giả sử rằng điều đó là có thể. Các cuộc gọi đến các phương thức đó sẽ thất bại và tạo ra hành vi không xác định (nhưng thường là thảm họa).

Vì vậy, tôi chắc chắn điều đó là không thể.

+0

Không xác định thường * có nghĩa là * thảm khốc! ;) –

+0

catch (UndefinedMethod/UndefinedClassException)? :-P – user420667

+3

@ user420667 Có 'MissingMethodException' và' TypeLoadException'. Chúng có thể xảy ra khi bạn xây dựng mã của bạn dựa trên một phiên bản của một assembly, nhưng sau đó chạy nó với một phiên bản khác, thiếu phương thức hoặc kiểu. – svick

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