Getting rid of magic strings in Raise Property Event
I really dislike magic strings in code, and whenever I can I try to avoid using them either by using constants and what have you. So you can imagine what I felt like when I started raising property change events – all those strings – drive me nuts. Basically copy and paste merchants out there can introduce a whole host of hideous bugs and so I played around with the code so it takes a property delegate into it and uses reflection to raise the correct property name.
So instead of this:
1: /// <summary>
2: /// Gets or sets a random property
3: /// </summary>
4: public int RandomProperty
5: { 6: get 7: {8: return this.randomProperty;
9: } 10: 11: set 12: {13: if (!this.randomProperty.Equals(value))
14: {15: this.randomProperty = value;
16: this.RaisePropertyChanged("RandomProperty");
17: } 18: } 19: }Yuk magic string. You can do this
1: /// <summary>
2: /// Gets or sets a random property
3: /// </summary>
4: public int RandomProperty
5: { 6: get 7: {8: return this.randomProperty;
9: } 10: 11: set 12: {13: if (!this.randomProperty.Equals(value))
14: {15: this.randomProperty = value;
16: this.RaisePropertyChanged(() => this.RandomProperty);
17: } 18: } 19: }By putting the following in a base class.
1: /// <summary>
2: /// Raise property event based passed property expression
3: /// </summary>
4: /// <typeparam name="T">Type of property</typeparam>
5: /// <param name="propertyExpresssion">Property expression</param>
6: protected void RaisePropertyChanged<T>(Expression<Func<T>> propertyExpresssion)
7: {8: var propertyName = this.ExtractPropertyName(propertyExpresssion);
9: this.RaisePropertyChanged(propertyName);
10: } 11: 12: /// <summary>
13: /// Extracts property name based on reflection
14: /// </summary>
15: /// <typeparam name="T">Type of property</typeparam>
16: /// <param name="propertyExpression">Property expression</param>
17: /// <returns>Property name</returns>
18: private string ExtractPropertyName<T>(Expression<Func<T>> propertyExpression)
19: {20: if (propertyExpression == null)
21: {22: throw new ArgumentNullException("propertyExpression");
23: } 24: 25: var memberExpression = propertyExpression.Body as MemberExpression;
26: if (memberExpression == null)
27: {28: throw new ArgumentException(@"The expression is not a member access expression.", "propertyExpression");
29: } 30: 31: var property = memberExpression.Member as PropertyInfo;
32: if (property == null)
33: {34: throw new ArgumentException(@"The member access expression does not access a property.", "propertyExpression");
35: } 36: 37: if (!property.DeclaringType.IsAssignableFrom(this.GetType()))
38: {39: throw new ArgumentException(@"The referenced property belongs to a different type.", "propertyExpression");
40: } 41: 42: var getMethod = property.GetGetMethod(true);
43: if (getMethod == null)
44: {45: // this shouldn't happen - the expression would reject the property before reaching this far
46: throw new ArgumentException(@"The referenced property does not have a get method.", "propertyExpression");
47: } 48: 49: if (getMethod.IsStatic)
50: {51: throw new ArgumentException(@"The referenced property is a static property.", "propertyExpression");
52: } 53: 54: return memberExpression.Member.Name;
55: }Much better…