It seems that early on in the design process, you decided to support string parameters in the constructors of different Attributes. While everything is very consistent, I'm not a huge fan for a few reasons:
Strings are brittle and liable to break-- rename a field or function and you'll have to go back and edit all the attributes referring to it. (I'm a purist and type safety/compile-time checks are important to me! :P)
There's no easy way to share properties between attributes in different files. Instead, you have to duplicate the same private variable or function to get the same functionality.
Take the following example:
Say I have a list of enemy names, defined in a static variable
Enemy.Names. In various other files, I'd like to use the
[ValueDropdown] attribute. Unfortunately, because it takes a string as argument, I can't refer to the static variable
Enemy.Names, but have to create a private variable or getter that references it for every file.
Alternatively, in a potential v2 of the API, we could create the additional constructors:
ValueDropdown(IList<T> dropdown) ValueDropdown(Func<IList<T>> dropdownFunc)
which behave identically to the current constructor, except they skip the Reflection step of finding the private method or variable.
Now I can do things like
[ValueDropdown(Enemy.Names)]-- problem solved!
This could extend to more than just ValueDropdown: VisibleIf, ValidateInput, OnInspectorGUI, etc. could all benefit from this.