5

Please bear with me if this question isn't well formulated. Not knowing is part of the problem.

An example of what I'd like to accomplish can be found in PropertyChangedEventArgs in WPF. If you want to flag that a property has changed in WPF, you do it like this:

PropertyChanged(this, new PropertyChangedEventArgs("propertyName"));

You pass a string to PropertyChangedEventArgs that refers to the property name that changed.

You can imagine that I don't really want hard coded strings for property names all over my code. Refactor-rename misses it, of course, which makes it not only aesthetically unappealing but error prone as well.

I'd much rather refer to the property itself ... somehow.

PropertyChanged(this, new PropertyChangedEventArgs(?SomeClass.PropertyName?));

It seems like I should be able to wrap this in a short method that lets me say something like the above.

private void MyPropertyChanged(??) {
  PropertyChanged(this, new PropertyChangedEventArgs(??.ToString()??));
}

... so I can say something like:
MyPropertyChanged(Person.Name); //where I'm interested in the property *itself*

So far I'm drawing a blank.

Jeffrey Knight
  • 5,888
  • 7
  • 39
  • 49
  • see also http://stackoverflow.com/questions/388775/how-do-i-get-the-name-of-a-property-from-a-property-in-c-2-0 – Jeffrey Knight May 13 '09 at 15:43
  • http://weblogs.asp.net/cazzu/archive/2006/07/06/Linq-beyond-queries_3A00_-strong_2D00_typed-reflection_2100_.aspx – Sam Saffron Aug 29 '12 at 21:04
  • possible duplicate of [Get method name and type using lambda expression](http://stackoverflow.com/questions/273941/get-method-name-and-type-using-lambda-expression) – nawfal Apr 27 '13 at 12:56

3 Answers3

6

There isn't a direct way to do this, unfortunately; however, you can do it in .NET 3.5 via Expression. See here for more. To copy the example:

PropertyInfo prop = PropertyHelper<Foo>.GetProperty(x => x.Bar);

(it is pretty simple to change that to return the name instead of the PropertyInfo).

Likewise, it would be pretty simple to write a variant:

OnPropertyChanged(x=>x.Name);

using:

OnPropertyChanged<T>(Expression<Func<MyType,T>> property) {...}
Community
  • 1
  • 1
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
1

This is a frequently requested feature, usually called infoof ("info of"), which would return the reflection object associated with a member, e.g.

PropertyInfo pi = infoof(Person.Name);

Sadly the dynamic keyword is absorbing the C# compiler team's time instead!

Daniel Earwicker
  • 114,894
  • 38
  • 205
  • 284
  • Coincidentally, just last week I wrote a blog article about "why no infoof yet?" Expect it later this month. – Eric Lippert May 13 '09 at 01:05
  • Cool, does it says "Because we're giving you something else as a surprise feature in C# 4 that does the same thing but even better than you ever imagined!!"? *crosses fingers* – Daniel Earwicker May 13 '09 at 09:55
  • Nope. It says "the feature is too much work for the benefit it produces". Sorry to disappoint. – Eric Lippert May 13 '09 at 15:33
1

I'm pretty confident there's no way to avoid specifying a string - there's no feature built into C# or .NET that allows you to pass references to properties, as far as I know, and passing a string to the Reflection API is by far going to be the simplest method.

However, outside of standard .NET, you might find your solution in PostSharp (Aspect Oriented Programming for .NET), which allows you add code that automates raising events when various properties change, as you have demonstrated in your question.

Noldorin
  • 144,213
  • 56
  • 264
  • 302
  • The Expression API allows this - looks at the "See here" in my answer for an example. – Marc Gravell May 12 '09 at 23:17
  • @Marc: Yeah, it seems you're right, though that is an awfully round-about method. Moreover, it does seem rather ugly to me (at least, the syntax is convoluted), but who am I to say... that may be what the asker prefers. – Noldorin May 12 '09 at 23:22