Construtor de Atributos Com Lambda
istoé possível fazer isso:
public static void SomeMethod<TFunc>(Expression<TFunc> expr)
{
//LambdaExpression happily excepts any Expession<TFunc>
LambdaExpression lamb = expr;
}
e chamá-lo em outro lugar passando um lambda para o parâmetro:
SomeMethod<Func<IQueryable<Person>,Person>>( p=>p.FirstOrDefault());
Eu gostaria de passar uma expressão como um parâmetro para umconstrutor de atributo. É possível fazer o abaixo?
class ExpandableQueryAttribute: Attribute {
private LambdaExpression someLambda;
//ctor
public ExpandableQueryMethodAttribute(LambdaExpression expression)
{
someLambda = expression
}
}
//usage:
static LambdaExpression exp =
(Expression<Func<IQueryable<Person>, Person>>)
(p => p.FirstOrDefault());
[ExpandableQueryAttribute(exp)] //error here
// "An attribute argument must be a constant expression, typeof expression
// or array creation expression of an attribute parameter type"
Meu objetivo é especificar um método ou lambda no construtor do atributo (mesmo se eu tiver que declarar um método com nome completo e passar o nome do método de alguma forma, isso seria ótimo).
Os tipos de parâmetro podem mudar, mas é importante que o construtor de atributo possa receber esse parâmetro e, de alguma forma, possa atribuí-lo a um campo do tipo LambdaExpression.
Eu quero que a declaração do método lambda / seja um pouco acima da chamada para o construtor de atributo, ou inline, para que você não precise ir muito longe para ver o que está sendo passado.
Então, essas alternativas estariam bem, mas sem sorte em fazê-las funcionar:
public static ... FuncName(...){...}
[ExpandableQueryAttribute(FuncName)]
// ...
ou
//lambdas aren't allowed inline for an attribute, as far as I know
[ExpandableQueryAttribute(q => q.FirstOrDefault())]
// ...
O trabalho existente é passar um ID de número para o construtor (satisfazendo o requisito "o argumento deve ser uma constante"), que é usado pelo construtor para fazer uma pesquisa em um dicionário onde as expressões foram adicionadas anteriormente. Estava esperando melhorar / simplificar isso, mas tenho a sensação de que ele não melhora devido a limitações nos construtores de atributos.