Lambdas son excelentes para muchos escenarios - pero si usted no quiere que ellos, tal vez simplemente no hace uso de ellos? Odio decirlo, pero las cadenas simples son probadas, especialmente para escenarios como el enlace de datos. Si desea un acceso rápido, puede ver HyperDescriptor, o hay formas de compilar un delegado en los descriptores de acceso de la propiedad, o puede compilar un Expression
desde la cadena y compilarlo (incluyendo un molde a object
si desea una firma conocida, en lugar de llamar al (mucho más lento) DynamicInvoke
).
Por supuesto, en la mayoría de los casos, incluso el reflejo crudo es lo suficientemente rápido, y no es el cuello de botella.
Sugiero comenzar con el código más simple, y compruebe que es en realidad demasiado lento antes de preocuparse de que sea rápido. Si no es demasiado lento, no lo cambie. Cualquiera de las opciones anteriores funcionaría de otra manera.
Otra idea; si está utilizando Expression
, usted podría hacer algo como:
public void IncludeProperties<T>(
Expression<Func<T,object>> selectedProperties)
{
// some logic to store parameter
}
IncludeProperties<IUser>(u => new { u.ID, u.LogOnName, u.HashedPassword });
y luego tomar la expresión separados? Un poco más ordenado, al menos ... aquí algunos ejemplos de código que muestra la deconstrucción:
public static void IncludeProperties<T>(
Expression<Func<T, object>> selectedProperties)
{
NewExpression ne = selectedProperties.Body as NewExpression;
if (ne == null) throw new InvalidOperationException(
"Object constructor expected");
foreach (Expression arg in ne.Arguments)
{
MemberExpression me = arg as MemberExpression;
if (me == null || me.Expression != selectedProperties.Parameters[0])
throw new InvalidOperationException(
"Object constructor argument should be a direct member");
Console.WriteLine("Accessing: " + me.Member.Name);
}
}
static void Main()
{
IncludeProperties<IUser>(u => new { u.ID, u.LogOnName, u.HashedPassword });
}
vez que conozca los MemberInfo
s (me.Member
en el anterior), la construcción de sus propios lambdas para el acceso individual debe ser trivial. Por ejemplo (incluyendo un yeso para object
para obtener una sola firma):
var param = Expression.Parameter(typeof(T), "x");
var memberAccess = Expression.MakeMemberAccess(param, me.Member);
var body = Expression.Convert(memberAccess, typeof(object));
var lambda = Expression.Lambda<Func<T, object>>(body, param);
var func = lambda.Compile();
oooh, bonita :) –
¿Cuál es la mejor manera de mantener las propiedades seleccionadas para un acceso rápido? ¿Lista? –
'MemberInfo' estaría bien; 'Func' (o 'Func ') estaría bien; un 'PropertyDescriptor' estaría bien (especialmente con HyperDescriptor). Funcionará de cualquier manera ... –