2016-08-25 12 views
5

Gần đây tôi đã có cuộc phỏng vấn với câu hỏi C#. Một trong số họ không thể tìm được câu trả lời.Câu đố phỏng vấn: truy cập thành viên dữ liệu cá nhân

tôi đã được đưa ra một lớp học, trông như thế này:

public class Stick 
{ 
    private int m_iLength; 
    public int Length 
    { 
     get 
     { 
      return m_iLength; 
     } 
     set 
     { 
      if (value > 0) 
      { 
       m_iLength = value; 
      } 
     } 
    } 
} 

Ngoài ra, một lớp học chính đã được đưa ra

static void Main(string[] args) 
{ 
    Stick stick = new Stick(); 
} 

Nhiệm vụ là để thêm mã vào chính mà sẽ gây ra m_iLength trong Lớp học Stick là tiêu cực (và nó đã được nhấn mạnh rằng nó có thể được thực hiện).

Tôi dường như bỏ lỡ điều gì đó. Thành viên dữ liệu là riêng tư, và theo như tôi biết hàm get và set là giá trị cho kiểu int, vì vậy tôi không thấy cách này có thể được thực hiện.

+3

phản ánh có thể? – slawekwin

+5

Ví dụ: http://stackoverflow.com/questions/10862747/access-private-fields – bobah75

+1

@Sayse trong C# bạn không thể ghi đè lên các thành viên lớp trừ khi chúng được khai báo "ảo" (tương phản với Java chẳng hạn). Reflection là cách duy nhất tôi có thể nhìn thấy (ngắn của sửa đổi IL cơ bản, hoặc sử dụng mã không an toàn để sửa đổi iLength sao lưu bộ nhớ - thậm chí không chắc chắn rằng cuối cùng là có thể!) –

Trả lời

4

Reflection luôn là trực tiếp nhất:

var type = typeof(Stick); 
var field = type.GetField("m_iLength", BindingFlags.NonPublic |BindingFlags.GetField | BindingFlags.Instance); 
field.SetValue(stick, -1); 
Console.WriteLine(stick.Length); 

Giải thích:

Dòng đầu tiên được đối tượng Type cho Stick, vì vậy chúng tôi có thể nhận được các lĩnh vực cá nhân sau này.

Dòng thứ hai nhận trường mà chúng tôi muốn đặt theo tên của nó. Lưu ý rằng các cờ ràng buộc là bắt buộc hoặc field sẽ là null.

Và dòng thứ ba cung cấp cho trường một giá trị âm.

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