E 'un po' poco chiaro su quali informazioni di tipo (se presenti) siano note durante il runtime. Piggybacking su Risposta di Nicholas Butler (dal momento in cui è stata accettata) Supponiamo che tu "sappia" il tipo di sorgente (cioè qual è il tipo di T nell'origine IQueryable) e "conoscerai" il tipo di destinazione (tipo di articolo restituito dal metodo di estensione IQueryable.Select). Quando dico "so", voglio dire che è qualcosa che può essere scoperto in fase di esecuzione senza dinamiche, riflessioni, late-binding, ecc. In caso contrario, la sua soluzione funzionerà solo se i tipi di origine e destinazione hanno proprietà con quei nomi corrispondenti (es. "Nome/Id" & "Nome/Valore").
Detto questo, c'è una soluzione molto semplice, senza dover costruire manualmente la tua espressione lambda ...
Soluzione: primo luogo permette di definire questi 2 tipi solo così sappiamo che cosa abbiamo a che fare con. Lo faccio solo perché non so quali tipi che si sta utilizzando, quindi queste sono davvero segnaposto per ciò che si sta realmente utilizzando, quindi questo non è necessario per la soluzione, solo per scopi di demo/esempio:
//this is whatever your source item type is (t)
public class NameIdPair
{
public string Name { get; set; }
public string Id { get; set; }
}
//this is whatever the SelectListItem type is you're using
public class SelectListItem
{
public string Name { get; set; }
public string Value { get; set; }
}
Quindi consente di definire una semplice classe statica con 2 metodi. Un metodo creerà l'espressione lambda e l'altro metodo convertirà e selezionare la sorgente (IQueryable) in IEnumerable:
public static class QueryableExtensions
{
public static IEnumerable<TItem> Select<TSource, TItem>(this IQueryable<TSource> source)
where TSource : NameIdPair
where TItem : SelectListItem, new()
{
if (source == null) throw new ArgumentNullException("source");
return source.Select(CreateLambda<TSource, TItem>());
}
public static Expression<Func<TSource, TItem>> CreateLambda<TSource, TItem>()
where TSource : NameIdPair
where TItem : SelectListItem, new()
{
return (t) => new TItem { Name = t.Name, Value = t.Id };
}
}
Usage:
//create an instance of an IQueryable<T> for demo purposes
var source = new[]
{
new NameIdPair {Name = "test1_name", Id = "test1_Id"},
new NameIdPair {Name = "test2_name", Id = "test2_Id"}
}.AsQueryable();
//you can call the "Select" extension method to select the queryable into an enum.
var enumerable = source.Select<NameIdPair, SelectListItem>();
//'enumerable' is an IEnumerable<SelectListItem> instance
//or if you just want the lambda expression...
var lambda = QueryableExtensions.CreateLambda<NameIdPair, SelectListItem>();
//lambda.ToString() returns "t => new SelectListItem() {Name = t.Name, Value = t.Id}";
Così ci si va. Non sono sicuro che sia quello che stai cercando, o se soddisfa le tue esigenze. Spero che qualcuno lo troverà utile.
se si conosce il tipo che è possibile utilizzare Enumerable.Cast: http://msdn.microsoft.com/en-us/library/bb341406.aspx –
Potrebbe essere un'opzione per trasmettere gli elementi a 'dynamic'? – Douglas
i suoni dinamici sono un'opzione migliore del riflesso. Sembra piuttosto imbarazzante usare la riflessione. Wy non puoi usare qualcosa che sia conforme a un'interfaccia come INameValuePair? – mathk