Solution
Since an attribute accepts a Type as a parameter (as long as this Type in>), you can use "creativity."
Then you need atributte to get a string array as a parameter but do not want to tell this array every time you decorate a member with this atributte , so you you want to get this array from a declaration elsewhere, a statement that you can change in the future or in some particular use of your attribute .
In order to have different declarations of the array that will be passed as parameter to the attribute, you can declare an interface:
interface IAttributeArgument
{
string[] Argument { get; }
}
Declare one of the arrays that can be used as your attribute parameter declaring a class that implements this interface:
class AttributeArgument : IAttributeArgument
{
public string[] Argument { get { return new string[] { "a", "b", "c" }; } }
}
Now the array can be passed as a parameter to your attribute like this:
[CustomAttribute(typeof(AttributeArgument))]
public void Metodo() { }
In your attribute implementation, you can create a Type instance passed by parameter and read the array like this:
class CustomAttribute : Attribute
{
public Type attributeArgument;
public CustomAttribute(Type attributeArgument)
{
this.attributeArgument = attributeArgument;
}
public string[] Argument
{
get
{
return ((IAttributeArgument)Activator.CreateInstance(attributeArgument)).Argument;
}
}
}
Tip: attributes are metadata declarations
This solution, as well as any other you find for what you want to do, is a swarm. See for example that attribute would accept any Type but wish to receive only a specific Type bad.
There is a reason for Attributes to accept a limited range of types as a parameter, and the reason is that atributte is a metadata declaration.
I repeat: statement . Decorating a member with an atributte adds metadata to it that should be able to be understood immediately by the programmer without having to resort to other points in the code.
That is, the ideal (expressive) way of passing parameters to an attribute is either a literal value or the expression of a literal value, such as a constant or an Enum .
An example of what would be an expressive use of attributes :
public class LinhaLidaDoArquivoTexto
{
[ColunaTipoData(ordem: 1, formatoData: "dd-MM-yyyy")]
public DateTime DataEnvio { get; set; }
[ColunaTipoDecimal(ordem: 2, formatoDecimal: "#0.00")]
public decimal ValorEnviado { get; set; }
...
}
The parameters passed to the attribute are not meant to be "variables". They are helping to express the class metadata expressively.