lambdas sont parfaits pour de nombreux scénarios - mais si vous ne voulez pas, peut-être tout simplement ne pas les utiliser? Je déteste le dire, mais des chaînes simples sont essayées et testées, en particulier pour des scénarios comme la liaison de données. Si vous voulez un accès rapide, vous pouvez regarder HyperDescriptor, ou il existe des moyens de compiler un délégué aux accesseurs de propriété, ou vous pouvez construire un Expression
à partir de la chaîne et le compiler (y compris un cast à object
si vous voulez une signature connue, plutôt que d'appeler le (beaucoup plus lent) DynamicInvoke
).
Bien sûr, dans la plupart des cas, même une réflexion grossière est assez rapide et n'est pas le goulot d'étranglement.
Je suggère de commencer par le code le plus simple, et vérifiez qu'il est effectivement trop lent avant de s'inquiéter de sa rapidité. Si ce n'est pas trop lent, ne le changez pas. Chacune des options ci-dessus fonctionnerait autrement.
Autre idée; si vous utilisez Expression
, vous pouvez faire quelque chose comme:
public void IncludeProperties<T>(
Expression<Func<T,object>> selectedProperties)
{
// some logic to store parameter
}
IncludeProperties<IUser>(u => new { u.ID, u.LogOnName, u.HashedPassword });
puis prendre l'expression à part? Un peu plus net, au moins ... voici quelques exemples de code montrant la deconstruction:
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 });
}
Une fois que vous connaissez les MemberInfo
s (me.Member
au-dessus), la construction de vos propres lambdas pour l'accès individuel devrait être trivial. Par exemple (y compris une distribution à object
pour obtenir une seule signature):
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, nice one :) –
Quelle est la meilleure façon de conserver les propriétés sélectionnées pour un accès rapide? Liste? –
'MemberInfo' serait bien; 'Func' (ou 'Func ') serait bien; un 'PropertyDescriptor' serait bien (en particulier avec HyperDescriptor). Cela fonctionnera dans les deux cas ... –