Bug InotifyPropertyChanged introdotto da refactoring, errore ortografico, distinzione tra maiuscole e minuscole ecc.
A volte cambiamo il nome di alcune nostre proprietà e ci dimentichiamo di cambiare la "stringa" che passiamo al metodo OnPropertyChanged()
( soprattutto quando chiamiamo questo metodo da qualche altra parte ), oppure semplicemente ortografarlo, incluso caso-disallineamento.
Qualcosa del genere:
public string FirstName //earlier it was simply 'Name'
{
get { return m_name; }
set
{
m_name = value ;
OnPropertyChanged("Name"); //still 'Name'. Bug!
//or, OnPropertyChanged("FirstNane"); //changed, but misspelled. Bug!
}
}
Fix
protected void OnPropertyChanged(string propertyName)
{
//this raises exception if there is something wrong (only in debug mode!).
RuntimeAssert.ValidatePropertyName(this, propertyName);
//your code here
}
Ecco l'implementazione della classe RuntimeAssert .
public static class RuntimeAssert
{
private static Dictionary<Type, List<string>> ClassPropertyMap = new Dictionary<Type, List<string>>();
private static List<string> GetProperties(Type type)
{
if (!ClassPropertyMap.ContainsKey(type))
{
PropertyInfo[] props = type.GetProperties(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
ClassPropertyMap.Add(type, new List<string>(props.Where(p => true).Select(p => p.Name)));
}
return ClassPropertyMap[type];
}
[Conditional("DEBUG")]
public static void ValidatePropertyName(object instance, string propertyName)
{
ValidatePropertyName(instance.GetType(), propertyName);
}
[Conditional("DEBUG")]
public static void ValidatePropertyName(Type type, String propertyName)
{
List<string> properties = RuntimeAssert.GetProperties(type);
if (!properties.Contains(propertyName))
{
string message = String.Format("Property '{0}' not found in class '{1}'", propertyName, type.FullName);
throw new PropertyNotFoundException(message);
}
}
}
E infine PropertyNotFoundException (è usato nella classe precedente).
public class PropertyNotFoundException : Exception
{
public PropertyNotFoundException(string message) : base(message)
{
}
}