Reputation: 12053
I would like to check by attribute that value passed to method is correct, because adding if condition to method body make code less readable (in my opinion)
For example,
public object GetSomething(int id)
{
// there could be more conditions
if (id<= 0)
throw new ArgumentOutOfRangeException(nameof(id), $"Forbiden value: '{id}'");
// real logic
...
I want to check it is such way
[PossitiveValueAttr(id)]
public object GetSomething(int id)
{
// real logic
or (I would prefer that)
public object GetSomething([PossitiveValueAttr] int id)
{
// real logic
1) Do you know any similar existing solution?
2) How can I pass method's argument to my attribute?
Upvotes: 0
Views: 64
Reputation: 1368
Inspired by Manfred...
So if for any method defined as
void DoSomething([Attr1] Type1 param1, [Attr2] Type2 param2, ...)
{
}
You're happy to add as the first statement of the method:
Validate(() => DoSomething(param1, param2, ...))
Where Attr1/Attr2 etc. all implement ValidationAttribute:
[AttributeUsage(AttributeTargets.Parameter)]
public class ArgumentAttribute : Attribute
{
public void Validate(string argumentName, object value)
{
// throw exception if not valid
}
}
Then you can implement Validate as:
static void Validate(Expression<Action> expr)
{
var body = (MethodCallExpression)expr.Body;
foreach (MemberExpression a in body.Arguments)
{
FieldInfo fi = a.Member as FieldInfo;
ParameterInfo pi = body.Method.GetParameters().FirstOrDefault(p => p.Name == fi.Name);
ValidationAttribute va = pi?.GetCustomAttribute<ValidationAttribute>();
if (va != null)
va.Validate(pi.Name, fi.GetValue(((ConstantExpression)a.Expression).Value));
}
}
And use it generically wherever you need to perform argument validation defined via custom attributes.
The main drawback is that ValidationAttribute can't be generic, so you always get a plain 'object' passed in that you'll have to downcast.
Upvotes: 1
Reputation: 1368
Attributes can't magically cause any behavioral change in your application unless you have code that looks for and acts on them. Further, attributes can only be determined if you have reflection information, which you can't get for function arguments. But for your particular example (must be positive), why not just used an unsigned int?
Upvotes: 0