views:

746

answers:

4

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.

A: 

you could use this trick.

Sam Saffron
+6  A: 

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) {...}
Marc Gravell
thanks -- great insight
Jeffrey Knight
+1  A: 

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
Coincidentally, just last week I wrote a blog article about "why no infoof yet?" Expect it later this month.
Eric Lippert
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
Nope. It says "the feature is too much work for the benefit it produces". Sorry to disappoint.
Eric Lippert
Never mind, I'll try crossing my toes next time.
Daniel Earwicker
+2  A: 

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
The Expression API allows this - looks at the "See here" in my answer for an example.
Marc Gravell
@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