Think Twice Before Throwing from Attribute Constructors
I had an interesting discussion recently about a subtle issue with custom attributes and I thought I'd share my conclusion. The question is whether it's a good practice to throw ArgumentException from an attribute constructor as in the following example:
[AttributeUsage(AttributeTargets.All)]
public class MyAttribute : Attribute {
private string value;
public MyAttribute(string value) {
if (value == null) throw new ArgumentNullException("value");
this.value = value;
}
public string Value {
get { return this.value; }
}
}
The idea is to express that a null 'value' argument represents an invalid use of MyAttribute. However, this error will not be surfaced at compile time when the malformed attrtibute is applied; it will be thrown at runtime when the attribute is retrieved via GetCustomAttributes. However, throwing ArgumentException then is inappropriate because there's nothing the caller can do to prevent it. Attribute constructors should capture their arguments as-is and let consumers handle the validation.