3

I have a custom attribute and I would like it to have the name of a property as input. Because the name is a string it is a valid input type (as attributes are quite limited as to what they can have as input to their constructors). But how can I accomplish this?

Take this example code:

public class MyCustomAttribute : Attribute {
    public MyCustomAttribute(string propertyName) {}
}

public class Foo {
    public bool MyCustomProperty { get; set; }

    [MyCustom(SomeMagicAppliedToMyCustomProperty)] // I want the attribute to receive something along the lines of "Foo.MyCustomProperty"
    public void Bar();
}

How can I accomplish this with the limitations to what an attribute can receive in its constructor?

TheHvidsten
  • 4,028
  • 3
  • 29
  • 62
  • Are you saying you want to pass in the _name of the property_ without hardcoding the string, or are you trying to pass in the _value stored in the property_ (which can't happen, as this is a compile time thing) – James Thorpe Jun 17 '15 at 09:41
  • Why not just do the magic in method? – danish Jun 17 '15 at 09:43
  • @JamesThorpe I want to pass the _name of the property_ without hardcoding the string. – TheHvidsten Jun 17 '15 at 10:13
  • 1
    The first stumbling point I can see is how it is supposed to know what property it is meant to be referring to if the attribute is on a different property. If you have rules for how you work out the property then is there any reason not to have them in your attribute to save the need to pass anything in at all? – Chris Jun 17 '15 at 10:25
  • What problem are you trying to solve? – hazzik Jun 17 '15 at 10:32

4 Answers4

5

There's a new feature in c#-6.0 nameof() that gives the name of the particular property, variable, class etc as a string,

http://www.c-sharpcorner.com/UploadFile/7ca517/the-new-feature-of-C-Sharp-6-0-nameof-operator/ https://msdn.microsoft.com/en-us/magazine/dn802602.aspx

samee
  • 156
  • 7
  • I read the links you provided, and it seems `nameof()` will only give the name of the property ("MyCustomProperty"), and not the fully qualified name ("Foo.MyCustomProperty"). Do you know if there are some extensions to `nameof()` that will give the full name? – TheHvidsten Jun 17 '15 at 12:48
  • You can refer to this Thread to pass full name using Reflection http://stackoverflow.com/questions/2308020/can-c-sharp-attributes-access-the-target-class – samee Jun 17 '15 at 13:05
3

This is not possible. The attributes can accept only constants, just put your MyCustomProperty name in quotes into the Attribute.

VitaliG
  • 52
  • 3
  • Even though there are some workaround as has been described in the other answers, they have a few limitations I couldn't live with. So this is the most correct answer. – TheHvidsten Jun 24 '15 at 09:36
3

You can also use CallerMemberNameAttribute https://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.callermembernameattribute.aspx

public CustomAttribute([CallerMemberName] string propertyName = null)
{
    // ...
}
samee
  • 156
  • 7
0

I've used this in an MVC5 application with C#6

private const string jobScheduleBindingAllowed = nameof(JobSchedule.JobId) + ", " + nameof(JobSchedule.Time) + ", " + nameof(JobSchedule.EndTime) + ", " + nameof(JobSchedule.TimeZoneId);

Then when I want to specify the bindings that are valid for the model:

[HttpPost]
public ActionResult CreateJobSchedule([Bind(Include = jobScheduleBindingAllowed)]JobSchedule jobSchedule)
{
    // stuff
}

Slightly cumbersome but better than having magic strings everywhere and is type safe so that errors due to renames can be caught at compile time.

ghostJago
  • 3,381
  • 5
  • 36
  • 51