这真的令人难以置信,但真实.此代码不起作用:
[AttributeUsage(AttributeTargets.Property|AttributeTargets.Field)]
public class Range : Attribute
{
public decimal Max { get; set; }
public decimal Min { get; set; }
}
public class Item
{
[Range(Min=0m,Max=1000m)] //compile error:'Min' is not a valid named attribute argument because it is not a valid attribute parameter type
public decimal Total { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
虽然这有效:
[AttributeUsage(AttributeTargets.Property|AttributeTargets.Field)]
public class Range : Attribute
{
public double Max { get; set; }
public double Min { get; set; }
}
public class Item …Run Code Online (Sandbox Code Playgroud) 这是可能做到这一点:
public static void SomeMethod<TFunc>(Expression<TFunc> expr)
{
//LambdaExpression happily excepts any Expession<TFunc>
LambdaExpression lamb = expr;
}
Run Code Online (Sandbox Code Playgroud)
并在其他地方调用它传递参数的lambda:
SomeMethod<Func<IQueryable<Person>,Person>>( p=>p.FirstOrDefault());
Run Code Online (Sandbox Code Playgroud)
我想改为将表达式作为参数传递给属性构造函数. 可以这样做吗?
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"
Run Code Online (Sandbox Code Playgroud)
我的目标是在属性的构造函数中指定方法或lambda(即使我必须声明一个完整的命名方法并以某种方式传递方法的名称,这样就可以了).
参数类型可以更改,但重要的是属性构造函数可以获取该参数,并以某种方式将其分配给LambdaExpression类型的字段
我希望lambda …
如此处所示,在您反映获取属性值之前,不会调用属性构造函数.但是,您可能也知道,只能将编译时常量值传递给属性构造函数.为什么是这样?我想很多人多喜欢做这样的事情:
[MyAttribute(new MyClass(foo, bar, baz, jQuery)]
Run Code Online (Sandbox Code Playgroud)
而不是传递一个字符串(导致字符串类型的代码!)与这些值,变成字符串,然后依靠Regex尝试获取值而不是仅使用实际值,而不是使用编译时警告/错误取决于对于可能抛出与该类无关的异常,除了它调用的方法使用了一些键入错误的属性.
这有什么限制?