2011-09-23 56 views
9

Tôi có thiết lập hoạt động không được đánh máy mạnh và dựa vào sự phản chiếu.Biểu thức lambda là thuộc tính

Tôi có một lớp học, nói

class Person{ 

    public string FirstName {get ; set;} 
    public string LastName {get; set;} 
    public int Age {get; set;} 
    ... 
    // some more public properties 
} 

class CellInfo { 
    public string Title {get; set;} 
    public string FormatString {get; set;} 
} 

và tôi có một cuốn từ điển như thế này

Dictionary<string, CellInfo> fields = new Dictionary<string, CellInfo>(); 
fields.Add("FirstName", new CellInfo {Title = "First Name", FormatString = "Foo"}); 
fields.Add("LastName", new CellInfo {Title = "Last Name", FormatString = "Bar"}); 

Đó là một từ điển đơn giản với tên bất động sản và một số thông tin về chúng. tôi vượt qua từ điển khác mô-đun xử lý các trường hợp người và tôi làm

Dictionary<string, CellInfo> fields = SomeMethodToGetDictionary(); 
foreach(Person p in someCollection) 
{ 
    foreach(var field in fields) 
    { 
     object cellValue = type(Person).GetProperty(field.Key).GetValue(p, null); 
     // use cellValue and info on field from field.Value somewhere. 
     ... 
    } 
} 

Phương pháp này đi qua các chuỗi cho tên trường và sử dụng phản ánh hoạt động, nhưng tôi đã tự hỏi nếu có một phương pháp mạnh mẽ, đánh máy làm điều này.

gì tôi nghĩ trong đầu đã có một tài sản đó được lưu trữ một biểu thức LINQ, một cái gì đó như thế này

fields.Add("FirstName", new CellInfo 
        { 
         Title = "First Name", 
         FormatString = "Foo", 
         EvalExpression = p => p.FirstName 
        }); 

và trong quá trình sử dụng, bằng cách nào đó sử dụng EvalExpression trên một đối tượng người và nhận được giá trị tài sản. Tôi không có đầu mối bắt đầu từ đâu hoặc cú pháp sẽ như thế nào để có một tài sản như thế này có thể đánh giá được. Tôi mới làm quen với các đại biểu và biểu thị cây mà tôi thậm chí không biết từ khóa phù hợp để tìm kiếm. Hy vọng mô tả của tôi là rõ ràng; nếu không, hãy cho tôi biết và tôi sẽ chi tiết khi cần thiết. Mọi hỗ trợ sẽ được đánh giá cao.

Trả lời

1

Bạn có thể thử một cái gì đó như thế này để không phải mã tên tài sản như dây đàn nếu đây là những gì bạn có nghĩa là bằng cách nói mạnh mẽ gõ:

class CellInfo<T> 
{ 
    public string Title { get; set; } 
    public string FormatString { get; set; } 
    public Func<T, object> Selector { get; set; } 
} 

Dictionary<string, CellInfo<Person>> dict = new Dictionary<string, CellInfo<Person>>(); 

dict.Add("LastName", new CellInfo<Person> { Selector = p => p.LastName }); 
dict.Add("Age", new CellInfo<Person> { Selector = p => p.Age }); 

foreach (Person p in someCollection) 
{ 
    foreach (var cellInfo in dict) 
    { 
     object value = cellInfo.Value.Selector(p); 
    } 
} 
-1

(Câu hỏi của bạn là rõ ràng nhưng dài. Trim những thứ ban đầu.)

Đây là cách sử dụng ASP.NET MVC phản ánh và lambda biểu thức để tạo tên trường trên đầu vào HTML, vv Vì vậy, bạn có thể có một nhìn vào mã nguồn cho vấn đề đó.

Trong thuật ngữ đơn giản, bạn phải truyền biểu thức của mình sang biểu thức Thành viên và nhận tên. Dễ dàng:

MemberExpression memberExpression = EvalExpression.Body as MemberExpression; 
if (memberExpression == null) 
    throw new InvalidOperationException("Not a memberExpression"); 

if (!(memberExpression.Member is PropertyInfo)) 
    throw new InvalidOperationException("Not a property"); 

return memberExpression.Member.Name; // returns FirstName 
+0

Bất cứ ai quan tâm đến c bỏ sót tại sao downvote? – Aliostad

+0

Nó có thể là lệnh (trái ngược với yêu cầu) trên dòng đầu tiên. – MikeKulls

0

Tôi nghĩ đại biểu là những gì bạn cần. Một cái gì đó như thế này:

public delegate string EvalExpressionDelegate (Person); 

class CellInfo 
{ 
    public string Title {get; set;} 
    public string FormatString {get; set;} 
    public EvalExpressionDelegate EvalExpression = null; 
} 

fields.Add("FirstName", new CellInfo 
        { 
         Title = "First Name", 
         FormatString = "Foo", 
         EvalExpression = p => p.FirstName 
        }); 
+0

+1 Thông tin tốt. Tôi đoán 'Func ' là một cách viết tắt cho đại biểu bạn có và một người nào đó đã không nhận ra điều đó và đã cho bạn một downvote. –

+0

@ProfessorChaos Tôi nghĩ rằng downvote có lẽ là do viết ra các đại biểu được coi là cách cũ thời làm nó mặc dù nó có thể có lợi thế của nó như đặt tên các tham số. – MikeKulls

2

Sử dụng một đại biểu :

class CellInfo { 
    public string Title {get; set; } 
    public string FormatString {get; set; } 
    public Func<Person, object> EvalExpression { get; set; } 
} 

Sau đó, đầu vào lambda của bạn sẽ làm việc ...

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