2012-01-24 13 views
7

Vì tôi có IEnumerable<T>, trong đó T là đối tượng bất kỳ, làm cách nào tôi có thể chọn một thuộc tính cụ thể, vì tôi biết tên của một trong các tên thuộc tính tại thời gian chạy dưới dạng chuỗi?Làm thế nào tôi có thể tạo một Chọn động trên một số điện thoại IE2 có thể đếm được trong thời gian chạy?

Ví dụ:

var externalIEnumerable = DataPassedFromConsumingCode(); // `IEnumerable<T>` 

string knownPropertyName = "Foo"; 
var fooSelect = externalIEnumerable.Select(...); 

Về bản chất, tôi rõ ràng chỉ làm externalIEnumerable.Select(x=> x.Foo);, nhưng tôi cần phải thực hiện Select này khi chạy, khi tôi không có quyền kiểm soát khi nó được tạo ra ban đầu.

-

ĐÁP: Dựa trên câu trả lời AlanT của, đây là những gì tôi thực sự đã làm:

public Expression<Func<TItem, object>> SelectExpression<TItem>(string fieldName) 
{ 
    var param = Expression.Parameter(typeof(TItem), "item"); 
    var field = Expression.Property(param, fieldName); 
    return Expression.Lambda<Func<TItem, object>>(field, 
     new ParameterExpression[] { param }); 
} 

Tôi giữ nó như một biểu thức, bởi vì gọi Compile gây ra IQueryable được liệt kê, trong đó có nghĩa là cơ sở dữ liệu bị tấn công không cần thiết. Vì vậy, để sử dụng nó, tôi chỉ làm những việc sau:

string primaryKey = _map.GetPrimaryKeys(typeof(TOriginator)).Single(); 
var primaryKeyExpression = SelectExpression<TOriginator>(primaryKey); 
var primaryKeyResults = query.Select(primaryKeyExpression).ToList(); 
+0

bạn có thể hạn chế T trong IEnumerable không? – Jason

+1

Đây không phải là câu hỏi cụ thể về LINQ, phải không? Bạn đang yêu cầu cách truy cập một thuộc tính động bằng tên chứ không phải tĩnh trong mã? –

+0

Để làm rõ, T của bạn có thể là bất cứ điều gì, tài sản của bạn có thể là bất cứ điều gì, bạn chỉ đơn giản sẽ có tên tài sản như một chuỗi? –

Trả lời

6

Có thể thực hiện điều này bằng một Expression

ví dụ

private class Foo { 
    public string Bar { get; set; } 
} 

private IEnumerable<Foo> SomeFoos = new List<Foo>() { 
    new Foo{Bar = "Jan"}, 
    new Foo{Bar = "Feb"}, 
    new Foo{Bar = "Mar"}, 
    new Foo{Bar = "Apr"}, 
}; 

[TestMethod] 
public void GetDynamicProperty() { 

     var expr = SelectExpression<Foo, string>("Bar"); 
     var propValues = SomeFoos.Select(expr); 

     Assert.IsTrue(new[] { "Jan", "Feb", "Mar", "Apr" }.SequenceEqual(propValues)); 

    } 

public static Func<TItem, TField> SelectExpression<TItem, TField>(string fieldName) { 

    var param = Expression.Parameter(typeof(TItem), "item"); 
    var field = Expression.Property(param, fieldName); 
    return Expression.Lambda<Func<TItem, TField>>(field, new ParameterExpression[] { param }).Compile(); 

} 

hth,
Alan.

0

Bạn có thể chủ động xây dựng một Expression<Func<T, U>>.

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