Skip to content

Instantly share code, notes, and snippets.

@jehugaleahsa
Last active February 2, 2016 15:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jehugaleahsa/73124c376d3251791937 to your computer and use it in GitHub Desktop.
Save jehugaleahsa/73124c376d3251791937 to your computer and use it in GitHub Desktop.
Smart or stupid...
public abstract class ObservableModel<TModel> : INotifyPropertyChanged
where TModel : ObservableModel<TModel>
{
private readonly Dictionary<PropertyInfo, object> lookup;
protected ObservableModel()
{
this.lookup = new Dictionary<PropertyInfo, object>();
}
public event PropertyChangedEventHandler PropertyChanged;
protected T Get<T>(Expression<Func<TModel, T>> getter)
{
PropertyInfo property = getProperty(getter);
return getValue<T>(property);
}
private T getValue<T>(PropertyInfo property)
{
if (lookup.ContainsKey(property))
{
return (T)lookup[property];
}
else
{
T value = default(T);
lookup.Add(property, value);
return value;
}
}
protected void Set<T>(Expression<Func<TModel, T>> setter, T value)
{
PropertyInfo property = getProperty(setter);
setValue<T>(property, value, EqualityComparer<T>.Default);
}
private void setValue<T>(PropertyInfo property, T value, IEqualityComparer<T> comparer)
{
T original = getValue<T>(property);
if (comparer.Equals(value, original))
{
return;
}
lookup[property] = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(property.Name));
}
}
private static PropertyInfo getProperty<T>(Expression<Func<TModel, T>> accessor)
{
MemberExpression memberExpression = accessor.Body as MemberExpression;
if (memberExpression == null)
{
throw new InvalidOperationException("The expression must refer to a property.");
}
PropertyInfo property = memberExpression.Member as PropertyInfo;
if (property == null)
{
throw new InvalidOperationException("The expression must refer to a property.");
}
if (!property.DeclaringType.IsAssignableFrom(typeof(TModel)))
{
throw new InvalidOperationException("The expression must refer to a property of the current type.");
}
return property;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment