13

Is there a way to get the name of the current property in a getter/setter?

Something like this:

public string MyProperty
{
    get { return base.Get<string>(nameof(ThisProperty)); }
    set { base.Set<string>(nameof(ThisProperty), value); }
}

nameof(ThisProperty) should resolve to "MyProperty".

Protector one
  • 6,926
  • 5
  • 62
  • 86
evaenrique
  • 981
  • 2
  • 8
  • 17
  • 2
    `nameof(MyProperty)` should work just fine? – MarcinJuraszek Mar 31 '16 at 15:42
  • 5
    Why should there? What is the problem with writing `nameof(MyProperty)`? – René Vogt Mar 31 '16 at 15:42
  • This could be useful in a case where the name `MyProperty` might change: then, you have to remember to update `nameof(whatever)`, although the Visual Studio IDE should catch this problem. – levelonehuman Mar 31 '16 at 15:43
  • 1
    @levelonehuman yes, the IDE should catch this as this was (afaik) one of the main reasons for introducing `nameof`. – René Vogt Mar 31 '16 at 15:48
  • I came across this question when using MVVM's `RaisePropertyChanged(nameof(ThisProperty))` method and trying to avoid cut and paste issues when generating new properties. I then looked more closely at MVVMLight's method signature and saw they already have an overload for `RaisePropertyChanged()` defined as `public virtual void RaisePropertyChanged([CallerMemberName] string propertyName = null);` exactly for this purpose :-) – Simon_Weaver Oct 23 '17 at 00:37

2 Answers2

26

It can't be done with nameof, but there's an even better way (available since C# 5). You can make the propertyName parameter optional and apply the CallerMemberName attribute to it:

protected void Set<T>(T value, [CallerMemberName] string propertyName = null)
{
    ...
}

protected T Get<T>([CallerMemberName] string propertyName = null)
{
    ...
}

Now if you omit the argument for propertyName, the current member name is passed implicitly:

public string MyProperty
{
    get { return base.Get<string>(); } // same as calling Get<string>("MyProperty")
    set { base.Set<string>(value); } // same as calling Set<string>(value, "MyProperty")
}
Thomas Levesque
  • 286,951
  • 70
  • 623
  • 758
  • This is an amazing answer! Thank you sir! – Smartis has left SO again Apr 01 '16 at 06:23
  • 1
    I beg to differ with your first sentence. As of C# 6, `nameof` will actually do the job: `public string MyProperty { get { return base.Get(nameof(MyProperty)); } set { base.Set(nameof(MyProperty), value); } }` – takrl Apr 04 '16 at 11:39
  • @takrl, I think the OP wanted to get the name of the property without having to specify it explicitly. If you use `nameof(MyProperty)`, you still have to write `MyProperty` yourself (admittedly, it's still better than writing it as a string) – Thomas Levesque Apr 04 '16 at 11:42
  • I agree that the use of `[CallerMemberName]` is probably better in this context, but still, the first sentence seems to suggest nameof doesn't work for properties, which is not true. – takrl Apr 04 '16 at 11:54
  • Is it not suppose to be : "[CallerMemberName] string propertyName = null" ? – pascx64 Oct 28 '17 at 03:46
-3

Alternative is to the the MethodBase since a Get and Set are essentially methods.

public string MyProperty
{
    get
    {
        return MethodBase.GetCurrentMethod().Name.Substring(4);
    }            
}

The substring is there because each name is prefixed with get_ and set_

This returns MyProperty as the result.

CathalMF
  • 9,705
  • 6
  • 70
  • 106