2009-12-08 26 views
16

Làm cách nào tôi có thể nhận được giá trị của parms (trong vòng lặp sử dụng phản chiếu). Trong câu hỏi trước, ai đó đã chỉ cho tôi cách lặp qua các parm bằng cách sử dụng sự phản chiếu.C# Nhận giá trị của parms bằng cách sử dụng phản chiếu

static void Main(string[] args) 
{ 
    ManyParms("a","b","c",10,20,true,"end"); 
    Console.ReadLine(); 
} 

static void ManyParms(string a, string b, string c, int d, short e, bool f, string g) 
{ 
    var parameters = MethodBase.GetCurrentMethod().GetParameters(); 
    foreach (ParameterInfo parameter in parameters) 
    { 
     string parmName = parameter.Name; 
     Console.WriteLine(parmName); 
     //Following idea required an object first 
     //Type t = this.GetType(); 
     //t.GetField(parmName).GetValue(theObject)); 

    } 
} 

Nếu bạn phải biết tại sao tôi muốn làm điều này, xin vui lòng xem tại đây: .NET Reflection of all method parameters


Cảm ơn tất cả - nó có vẻ như trong Python, Perl, PHP này sẽ được dễ dàng.
Mặc dù nó có thể không phản ánh, nếu tôi sử dụng sự phản chiếu để lấy tên trường, có vẻ như sẽ có một cách năng động dễ dàng để lấy giá trị dựa trên tên. Tôi chưa thử AOP (Lập trình hướng khía cạnh) các giải pháp. Đây là một trong những điều mà nếu tôi không thể làm điều đó trong một hoặc hai giờ, tôi có lẽ sẽ không làm điều đó.

+0

Có lẽ một cái gì đó có thể được thực hiện bằng cách kiểm tra thông qua phản ánh máy nhà nước được tạo ra khi bạn sử dụng một IEnumerable? Chỉ cần một ý tưởng tôi sẽ không biết làm thế nào để nhận ra bản thân mình :-) (Bình luận ở đây vì một câu hỏi trùng lặp ngày hôm nay) – Jbjstam

Trả lời

19

Bạn có thể không, về cơ bản - ít nhất là không phải không tham gia vào debugger/profiling API.

Theo lý thuyết, có có thể là một số cách để hiển thị giá trị tham số, nhưng không - và tôi nghi ngờ rằng để làm như vậy, bạn phải loại bỏ một số tối ưu.

4

Bạn không thể phản ánh và bạn không nên làm điều đó.

Nếu bạn cần loại chức năng này, hãy sử dụng proxy, ví dụ: thông qua triển khai RealProxy chặn cuộc gọi cho bạn. Sau đó, bạn có thể kiểm tra và sửa đổi bất kỳ thông số nào trước khi thực hiện cuộc gọi thực tế (hoặc thậm chí không thực hiện cuộc gọi ban đầu, tùy thuộc vào bạn).

+0

Tôi sẽ xem xét điều này nếu tôi có nhiều thời gian hơn. Tuy nhiên, nếu bạn thấy bài viết được tham chiếu ở trên, tôi đang sử dụng Máy chủ Tích hợp Máy chủ Microsoft và đặc biệt là HIP - và không chắc chắn về cách proxy sẽ chơi với những người đó. – NealWalters

4

Bạn không thể làm điều đó. Phản ánh hoạt động trên siêu dữ liệu được nhúng trong quá trình biên dịch và tại thời điểm đó các giá trị tham số không được biết.

+4

Nhưng bạn có thể sử dụng sự phản chiếu để lấy các giá trị của các thuộc tính trong các đối tượng - mà không được biết tại thời gian biên dịch. – NealWalters

4

Bạn đã cân nhắc sử dụng AOP, chẳng hạn như PostSharp?

Có thể truy cập vào các giá trị đối số trước khi phương thức của bạn thực hiện và mã của bạn sẽ được giảm xuống thành thuộc tính có thể sử dụng lại và thuộc tính được áp dụng cho các phương thức cần có kiểm tra này.

2

Bạn không thể nhận được giá trị của tham số của phương thức bằng cách sử dụng phản chiếu. Bởi vì phản ánh trả về thông tin siêu dữ liệu. Nếu bạn muốn nhận giá trị của một trường hoặc thuộc tính cụ thể, bạn cũng cần phải sử dụng một cá thể (như bạn đã biết).

Có một số cách để có được giá trị của thông số bằng cách sử dụng hệ thống ống nước bên trong của khung công tác .NET - cụ thể là API hồ sơ và API trình gỡ lỗi.

Bạn có thể sử dụng AOP cho những gì bạn đang cố gắng làm, có một dự án Codeplex gọi là CThru có thể giúp bạn - sử dụng CThru bạn có thể chặn phương thức khi nó được gọi và nhận các tham số được gọi.

32

Bạn có thể hack theo cách của bạn xung quanh điều này bằng cách tạo ra một loại vô danh bên trong phương pháp của bạn và tận dụng lợi thế của initialisers chiếu. Sau đó bạn có thể thẩm vấn các thuộc tính của loại vô danh bằng cách sử dụng sự phản chiếu. Ví dụ:

static void ManyParms(
    string a, string b, string c, int d, short e, bool f, string g) 
{ 
    var hack = new { a, b, c, d, e, f, g }; 

    foreach (PropertyInfo pi in hack.GetType().GetProperties()) 
    { 
     Console.WriteLine("{0}: {1}", pi.Name, pi.GetValue(hack, null)); 
    } 
} 
+5

Điều đó đòi hỏi bạn phải thay đổi nội dung phương pháp của mình. Nếu bạn định làm điều đó, bạn chỉ có thể báo cáo các giá trị. Cú pháp này làm cho nó dễ dàng hơn một chút để làm như vậy, nhưng tôi nghi ngờ nó sẽ thực sự giúp OP. –

+0

@Jon: Bạn nói đúng, tất nhiên, nhưng điều này là * rất nhiều * ít gõ hơn làm bằng tay, và bởi vì không có nhiều dòng mã cứng như 'Console.WriteLine (" a: "+ a)' vv , có ít phạm vi lỗi hơn. – LukeH

+2

Đó là một workarround rực rỡ – Serge

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