Wednesday, March 7, 2007

Symbols in C# 3.0 (reloaded)

Someone pointed out in the comments that the GetPropertySymbol function I wrote in a previous post did not handle nested member expressions. For example this.GetPropertySymbol( o => o.Person.Name ) would only return "Name", not "Person.Name". At first I just told him how to do it. Then I decided to do it because I could use the opportunity to demonstrate some cool C# 3.0-style functional programming.





I wrote the algorithm in functional style to challenge you to start thinking this way. The Iterate method takes a function and an initial value and then returns that initial value and then the result of passing the value to the function, the result of which is then passed back to the function for the next value and so on and so on. I stole this function from Haskell. It works this way...

Iterate( x => x + 10, 0)

...returns the following stream...

0,10,20,30...

The initial member expression is passed to iterate and every time the next member expression is required the function takes the member expression and attempts to convert its inner expression to a member expression using the "as" operator. If this conversion fails the "as" operator returns null. Then the resulting data is piped through TakeWhile which ensures that the stream stops when the first null value is passed to it. Finally I aggregate the stream of member expressions into a string by concatenating the member names, separated by a period.

Pretty neat huh?

6 comments:

Anonymous said...

I think you could just stop at the MemberInfo, then get the FullName of the (declaring or reflected) type, and join it to the member name.

Jafar Husain said...

I don't believe that will work, but I could be wrong. Keep in mind the member info object will only give the name and type of the property name. The FullName property will just give me the type name which I do not need under the circumstances. It will not have information about previously nested property names. How could it?

JH said...

I believe that this only works to retrieve the MethodInfo for the property getter and won't work for the property setter as Func<T, void> is invalid. Correct?

JH said...

Cancel that.. PropertyInfo.GetSetMethod() should work. :S

Anonymous said...

情趣用品|情趣用品|情趣用品|情趣|情趣用品|情趣

Anonymous said...

I've refactored the original approach to work with a MVVM base class ala Josh Smith.

Looks like this:

protected virtual void OnPropertyChanged(Expression> propertyExpr)
{
string propertyName = ((MemberExpression)propertyExpr.Body).Member.Name;
OnPropertyChanged(propertyName);
}

You can call it within a derived class like this:

OnPropertyChanged(() => this.MyProperty);

I just didn't want to implement OnPropertyChanged in every derived class.

Ciao Toto

About Me

My photo
I'm a software developer who started programming at age 16 and never saw any reason to stop. I'm working on the Presentation Platform Controls team at Microsoft. My primary interests are functional programming, and Rich Internet Applications.