Archive

Archive for the ‘C#’ Category

Tracking Inter-Object Dependencies using Expression Trees (Part 2)

December 28th, 2008

This is the second part of an article that covers the usage of lambda expressions to monitor changes on complex object graphs. The first part can be found here and the third part (Lambda Binding) is here.

Latest Version: 1.0.3, 2009.04.03
Download Project: lambda-dependencies.zip

Introduction

 

The first part covered the basics of the framework based on a sample application where I monitored any changes on the object graph MyStudent.School.Address.City with a simple lambda expression:

public MyApplication()
{
  //create a dependency on the city of the student's school
  var dep = DependencyNode.Create(() => MyStudent.School.Address.City);
}

 

The subsequent chapters discuss a few advanced topics that might be important when working with the API.

 

INotifyPropertyChanged vs. Manual Updates

In order to pick up a changed values on the dependency chain, the observed classes (in the sample: School, Student, Address) must implement the INotifyPropertyChanged interface. Otherwise, changes remain undetected.

This might not be a problem in case of immutable properties or fields, and it is perfectly valid to include classes that do not implement the interface. However: In case you don’t have INotifyPropertyChanged available (e.g. because you rely on a class in an external library), and changes do occur, you can manually update these node values by invoking the SetNodeValue method of an arbitrary dependency node.

public void SetFieldDependency()
{
  Student student = TestUtil.CreateTestStudent();

  //create dependency on the address field rather than the Address property
  var dep = DependencyNode.Create(() => student.School.address.City);
  dep.DependencyChanged +=
      (node, e) => Console.WriteLine("City: " + e.TryGetLeafValue());

  //exchange address
  var newAddress = new Address {City = "Stockholm"};
  student.School.address = newAddress;

  //get the node that represents the address
  var addressFieldNode = dep.FindNode(() => student.School.address);

  //set the node value manually and trigger change event
  addressFieldNode.SetNodeValue(newAddress, true);
}

 

Reacting to Sub Property and Target Collection Changes

In the sample above, we declared a dependency on the City property of an Address object. City is just a string, but what if we wanted to track *any* change on the school’s address? One way would be to declare dependencies for every single property of the address:

var student = TestUtil.CreateTestStudent("Harvard");

//create dependency on City
var dep1 = DependencyNode.Create(() => student.School.Address.City);
//create dependency on Street
var dep2 = DependencyNode.Create(() => student.School.Address.Street);
//...

 

This, however, is pretty tedious and there is a simpler solution: As Address implements INotifyPropertyChanged, we can just declare a dependency on the Address property of School.

var student = TestUtil.CreateTestStudent("Harvard");

//create dependency on address object
var dep1 = DependencyNode.Create(() => student.School.Address);

//output the changed property name and the change reason
dep1.DependencyChanged += (node, e) =>
      {
        string msg = "Changed property: {0}, change reason: {1}";
        Console.Out.WriteLine(msg, e.ChangedMemberName, e.Reason);
      };

//change the city
student.School.Address.City = "Ethon";

 

The above snippet registers with the DependencyChanged event and writes two properties of the event’s DependencyChangeEventArgs to the console: ChangedMemberName and the Reason. This produces the following console output:

Changed property: City, change reason: SubPropertyChanged

 

Note that this is a special case: The declared dependency chain is Student:School:Address while we received a change event for the City property, which is not part of the dependency chain!

I think that usually, this is a desired behavior, so this is the default. However, you can control this behavior by using a DependencyNodeSettings class and explicitly setting the ObserveSubValueChanges property:

var student = TestUtil.CreateTestStudent("Harvard");

//create settings class
var settings = new DependencyNodeSettings<Address>(() => student.School.Address);
settings.ChangeHandler = OnDependencyChanged;

//configure settings to ignore sub item changes
settings.ObserveSubValueChanges = false;

//does not cause a change event:
Student.School.Address.City = "Ethon";

 

Note that the same behavior goes for target items that are collections. If the target collection implements the INotifiyCollectionChanged interface, the dependency node fires the DependencyChanged event with a reason of TargetCollectionChange as soon as the contents of the targeted collection changes.

Weak References (and Deserved Credits)

A DependencyNode only maintains weak references. Even if it would not pick up an object that goes out of scope because no property change event was fired, this still wouldn’t stop the targeted object from being garbage collected. The same goes for node’s events and internal event listeners.

I’m using two very nice implementations for internal listeners and the exposed DependencyChanged event:

 

Limitations

This library solves a specific problem and currently operates solely on members, variables, and constant expressions – more complex expressions (such as LINQ queries) are currently out of the picture, but I’m open to suggestions. You might also look out for related projects, such as Bindable LINQ.

Author: Categories: C#, Dependencies Tags: ,

Tracking Inter-Object Dependencies using Expression Trees (Part 1)

December 28th, 2008

This is the first part of an article that covers the usage of lambda expressions to monitor changes on complex object graphs.

The second part can be found here.
The third part (Lambda Bindings) can be found here.

 

Latest Version: 1.0.3, 2009.04.03
Download Project: lambda-dependencies.zip

Introduction

In an ongoing project, I had to struggle with quite a few dependencies between objects, mainly with regards to validation. As a result, I came up with a generic solution based on lambda expressions.

But let’s start with an example. Imagine you have an application that references a Student that attends a a given School. And let’s assume, the school’s location (city) is of importance to you, so a changed city should trigger some action. My class model looks like this:

image

 

In order to keep track of the dependency on the school’s location, you have to observe quite a few things:

  • Whether the City property of the school’s Address object is changed.
  • Whether the Address object of the school itself is replaced by another instance.
  • Whether the referenced School object of the student is changed. This would require you to re-wire change listeners for the school and address.
  • Whether the referenced student instance itself is being replaced by setting the MyStudent property. Again, you would have to deregister all existing listeners and create new ones for the new student, school, and address.

 

This is a lot of error-prone and tedious work: You need to register and de-register event listeners, handle null references (a new School instance might not provide an Address at first) etc. This is where expression trees come to the rescue. Basically, you can reduce the plumbing to a single line of code:

 

public MyApplication()
{
  //create a dependency on the city of the student's school
  DependencyNode<string> dependency;
  dependency = DependencyNode.Create(() => MyStudent.School.Address.City);
}

 

The snippet above analyzes the submitted expression and resolves the dependency graph, which basically looks the following:

image

Dependency.Create returns an object of type DependencyNode. This node refers to the root of the expression tree, which is the MyApplication class that provides the MyStudent property. You can traverse the dependency chain in both directions through  the ChildNode and ParentNode properties should you ever want to. But usually (if at all!), you’ll need just two properties:

  • LeafValue returns the dependency target. In our sample, this is the string that is returned by the City property of the school’s Address.
  • If the school’s Address (or the School reference itself) would be set to null, there would not be a city at all. In this case, LeafValue just returns a value of null. However: You can check whether the graph from root to the dependency target is intact by evaluating the IsChainBroken property on any given node.

 

//get the city, if the dependency graph leads to a valid address
string city = dependency.IsChainBroken ? "NONE" : dependency.LeafValue;

(Note that LeafValue is a generic property. In this case, it is of type string)

image

 

Handling Changes in the Dependency Chain

As soon as a dependency is declared, the DependencyNode tries to register event listeners on all objects of the dependency graph in order to track changes and keep itself up-to-date. Furthermore, you can register an event listener with the node’s DependencyChanged event, which fires whenever a change in the dependency chain occurs. Event listeners receive an instance of DependencyChangeEventArgs that provide the changed node, property or field names, and the change reason:

image

 

Here’s a sample – the snippet below registers an event listener which basically just outputs the name of the student, the school name, and the city to the console:

 

public MyApplication()
{
  //create a dependency on the city of the student's school
  dependency = DependencyNode.Create(() => MyStudent.School.Address.City);
  dependency.DependencyChanged += OnStudentCityChanged;
}


/// <summary>
/// Invoked whenever the dependency graph between <see cref="MyStudent"/>
/// property and the <see cref="Address.City"/> of the student's
/// school is being changed.
/// </summary>
private void OnStudentCityChanged(object sender, DependencyChangeEventArgs<string> e)
{
  //get the changed node
  DependencyNode<string> changedNode = e.ChangedNode;

  //get student name, if we have one after all
  string studentName = myStudent == null ? "[none]" : myStudent.Name;

  //get the school name
  string school = "[none]";
  if (myStudent != null && myStudent.School != null)
  {
    school = myStudent.School.SchoolName;
  }

  //get the city, if the dependency graph leads to a valid address
  string city = changedNode.IsChainBroken ? "[unavailable]" : changedNode.LeafValue;

  //NOTE: You can also get the leaf value through this convenience method:
  //string city = e.TryGetLeafValue("[unavailable]");

  //write student/city to console
  string msg = "Student {0} goes now to school {1} in {2}";
  Console.Out.WriteLine(msg, studentName, school, city);
}

 

Once an event listener is registered, you can change properties on different levels of the dependency chain:

public void Test()
{
  //assign a student
  MyStudent = new Student { Name = "Lucy" };
  //set a school without an address
  MyStudent.School = new School {SchoolName = "University"};
  //assign an address
  MyStudent.School.Address = new Address {City = "Redmond"};
  //assign another address instance
  MyStudent.School.Address = new Address {City = "New York"};
  //change the City property of the address
  MyStudent.School.Address.City = "Washington";
  //cut the graph by removing the school reference
  MyStudent.School = null;
  //clear the MyStudent property completely
  MyStudent = null;
}

 

Every line of the above test method triggers the change event. Accordingly, the console output is the following:

Student Lucy goes now to school [none] in [unavailable]
Student Lucy goes now to school University in [unavailable]
Student Lucy goes now to school University in Redmond
Student Lucy goes now to school University in New York
Student Lucy goes now to school University in Washington
Student Lucy goes now to school [none] in [unavailable]
Student [none] goes now to school [none] in [unavailable]

 

Enjoy 🙂

kick it on DotNetKicks.com

Author: Categories: C#, Dependencies Tags: ,

IronPython: Reusing Import Symbols to Avoid Performance Hits

December 18th, 2008

I was struggling with IronPython today as I stumbled over a pretty annoying setback when it came to dynamic compilation of scripts that involved namespace imports.

Lets do an artificial sample: The snippet below just increments a variable by one. As expected, it executes blazingly fast – after compilation, it executes a few thousand times without getting over a single millisecond:

value = value + 1

 

Now look at the following example:

import clr
clr.AddReference('System.Xml')
from System.Xml import *
value = value + 1

 

Basically, this snippet performs the same logic (incrementing the ‘value’ variable), but it contains an import for the System.Xml namespace. It’s not necessary, but it still needs to be compiled. Executing this (compiled!) script 4000 times takes over 5 seconds!

 

However: If you are lucky (as me), you have the opportunity to separate namespace imports and business logic, so you basically end up with two scripts:

  • The import script, which is executed only once to get the imported symbols
  • A script that performs the actual work
 
//script 1
import clr
clr.AddReference('System.Xml')
from System.Xml import *

//script 2
value = value + 1

 

Of course, you still need the import from the first script to perform the second one – which is where symbol dictionaries come into play:

//a dictionary that receives the import simbols
var importSymbols = new SymbolDictionary();

//execute imports on our engine
ScriptSource importSource = engine.CreateScriptSourceFromString(imports,
    SourceCodeKind.Statements);
CompiledCode importCompiled = importSource.Compile();
//create a scop to populate the symbols with the imported types
ScriptScope importScope = engine.CreateScope(importSymbols);
importCompiled.Execute(importScope);

 

The statement above executes the import script with an empty SymbolDictionary. If you check this dictionary after execution, you can see that it now contains symbols for all types of the imported namespace:

importSymbols.Key = __builtins__
value = IronPython.Runtime.PythonDictionary

importSymbols.Key = clr
value = Microsoft.Scripting.Runtime.Scope

importSymbols.Key = IHasXmlNode
value = IronPython.Runtime.Types.PythonType

importSymbols.Key = IXmlLineInfo
value = IronPython.Runtime.Types.PythonType

importSymbols.Key = IXmlNamespaceResolver
value = IronPython.Runtime.Types.PythonType

... much more

 

What we can do now is reuse this retrieved symbols for our actual worker snippet  (but beware, there’s a catch):

//compile worker script
ScriptSource scriptSource = engine.CreateScriptSourceFromString(source,
  SourceCodeKind.Statements);
CompiledCode workerScript = scriptSource.Compile();

//creating our scope with the new symbols allows us to access
//the XML namespace
ScriptScope workerScope = engine.CreateScope(importSymbols);
workerScope.SetVariable("value", 10);
workerScript.Execute(workerScope);

 

However, this code is not thread-safe, because it causes different scopes to actually share not only the import symbols, but all variables through the symbol dictionary. Look at the code below, that creates to script scope instances which are initialized with individual values:

//create a new scope with the symbols of the import scope
ScriptScope run1 = engine.CreateScope(importSymbols);
//start with a value of 10
run1.SetVariable("value", 10);
workerScript.Execute(run1);

//create a second scope with the symbols of the import scope
ScriptScope run2 = engine.CreateScope(importSymbols);
//start with a value of 20
run2.SetVariable("value", 20);
workerScript.Execute(run2);

//both scopes actually share the same variable
Console.Out.WriteLine(run1.GetVariable<int>("value"));
Console.Out.WriteLine(run2.GetVariable<int>("value"));

 

The console outputs the same value both times – because both scopes operate on the same variable:

21
21

 

So basically, we have two requirements:

  • Store import symbols (or any other shared variables) in a reusable cache.
  • Store worker variables that belong to a given script scope in another dictionary.

 

We can do this by subclassing the CustomSymbolDictionary class of the Microsoft.Scripting.Runtime.BaseSymbolDictionary namespace. Took me ages to find a solution, but implementation was a breeze:

/// <summary>
/// A symbol dictionary that provides an fixed set of
/// symbols through a <see cref="SharedScope"/>. As new variables
/// are not added to the <see cref="SharedScope"/>, these cached
/// symbols can be reused across different scopes.
/// </summary>
public class SharedSymbolDictionary : CustomSymbolDictionary
{
  /// <summary>
  /// A script scope that provides a reusable set of symbols.
  /// Any variables that are being created by the <see cref="ScriptScope"/>
  /// that owns this cache are not stored within <see cref="SharedScope"/>,
  /// but the parent scope's own symbol dictionary.
  /// </summary>
  public ScriptScope SharedScope { get; private set; }


  /// <summary>
  /// Creates a new cache instance
  /// </summary>
  /// <param name="sharedScope">A reusable <see cref="ScriptScope"/> that provides
  /// a set of symbols that are supposed to be used across several scopes.</param>
  /// <exception cref="ArgumentNullException">If <paramref name="sharedScope"/>
  /// is a null reference.</exception>
  public SharedSymbolDictionary(ScriptScope sharedScope)
  {
    if (sharedScope == null) throw new ArgumentNullException("sharedScope");
    SharedScope = sharedScope;
  }



  /// <summary>
  /// Invoked if a given variable or symbol is being requested. This method
  /// tries to find the requested item in the underlying <see cref="SharedScope"/>.
  /// </summary>
  /// <param name="key"></param>
  /// <param name="value"></param>
  /// <returns>True if the <see cref="SharedScope"/> provides the requested
  /// symbol.</returns>
  protected override bool TryGetExtraValue(SymbolId key, out object value)
  {
    //return the key from the base scope, if possible.
    lock (SharedScope)
    {
      return SharedScope.TryGetVariable(SymbolTable.IdToString(key), out value);
    }
  }



  /// <summary>
  /// Gets a list of the extra keys that are cached by the the optimized
  /// implementation of the module.
  /// </summary>
  public override SymbolId[] GetExtraKeys()
  {
    lock (SharedScope)
    {
      return SharedScope.GetItems().Select(pair =>
        SymbolTable.StringToId(pair.Key)).ToArray();
    }
  }


  /// <summary>
  /// Tries to set the extra value and return true if the specified key
  /// was found in the list of extra values.<br/>
  /// Any attempts to store extra values are being denied, which causes
  /// them to be stored in the scope itself rather than the local
  /// <see cref="SharedScope"/>. This ensures that runtime variables are
  /// not shared between different instances of the cache.
  /// </summary>
  /// <param name="key">The key that is used to store the submitted
  /// value.</param>
  /// <param name="value">Value to be cached.</param>
  /// <returns>Always false because runtime symbols are not supposed
  /// to be stored within the cache. This causes the value to be stored
  /// within the internal dictionary of the base class.</returns>
  protected override bool TrySetExtraValue(SymbolId key, object value)
  {
    return false;
  }

}

 

 

With this implementation, we can change our snippet accordingly:

//create a new scope with the symbols of the import scope
SharedSymbolDictionary cache = new SharedSymbolDictionary(importScope);
ScriptScope run1 = engine.CreateScope(cache);
//start with a value of 10
run1.SetVariable("value", 10);
workerScript.Execute(run1);

//create a second scope with the symbols of the import scope
cache = new SharedSymbolDictionary(importScope);
ScriptScope run2 = engine.CreateScope(cache);
//start with a value of 20
run2.SetVariable("value", 20);
workerScript.Execute(run2);

//both scopes actually share the same variable
Console.Out.WriteLine(run1.GetVariable<int>("value"));
Console.Out.WriteLine(run2.GetVariable<int>("value"));
 
As the SharedSymbolDictionary class stores the value variable not in the shared importScope, the variables of the worker scope can be set independently, which produces the correct output:
 
11
21

 

And the performance gain is remarkable: Execution time is once again down to 17 milliseconds for 10’000 iterations 🙂

Download cache implementation and test script: symbolcache.zip

Author: Categories: C#, Open Source Tags:

A Covariant ObservableCollection for .NET 3.x

November 28th, 2008

When starting with generics, I was somewhat suprised that something like this didn’t work:

 

public interface IAnimal
{
}

public class Pig : IAnimal
{
}

public class AnimalFarm
{
  private ObservableCollection<Pig> pigs;

  public IEnumerable<IAnimal> Animals
  {
    get { return pigs; } //DOES NOT COMPILE
  }
}

 

The problem is that generics aren’t covariant, which is sometimes a bit of a problem when working with interfaces. However, while we’re waiting for C# 4.0, there is a poor man’s solution to covariance – the idea is to just expose the required IEnumerable<IAnimal> interface explicitly for the interface. And of course, there’s a generic solution to that problem:

 

/// <summary>
/// An implementation of <see cref="ObservableCollection{T}"/> that provides
/// an <see cref="IEnumerable{X}"/> interface for a super type of
/// <typeparamref name="T"/>.
/// </summary>
/// <typeparam name="T">The type of items to be stored in the collection.</typeparam>
/// <typeparam name="X">A super type of <typeparamref name="X"/>, for which this
/// collection provides an <see cref="IEnumerable{X}"/> interface, thus providing
/// covariance.</typeparam>
public class HybridObservableCollection<T, X> : ObservableCollection<T>,
                                                IEnumerable<X> where T : X
{

  /// <summary>
  /// Provides enumeration over type <see cref="X"/>.
  /// </summary>
  /// <returns>A <see cref="IEnumerator{X}"/>> that can be used to iterate
  /// through the collection.</returns>
  IEnumerator<X> IEnumerable<X>.GetEnumerator()
  {
    foreach (T t in this)
    {
      yield return t;
    }
  }

}

 

Note the type constraint: The second type parameter (X) must be convertible to the first one (T), which ensures that you can’t break the collection.

And as a result, we can return the collection as both IEnumerable<Pig> or IEnumerable<IAnimal>:

public class AnimalFarm
{
  //the collection provides both IEnumerable<Pig>, IEnumerable<IAnimal>
  private HybridObservableCollection<Pig, IAnimal> pigs;

  public IEnumerable<IAnimal> Animals
  {
    get { return pigs; } //WORKS
  }

  public IEnumerable<Pig> Pigs
  {
    get { return pigs; } //WORKS TOO
  }
}

 

Of course, rather than just IEnumerable<IAnimal>, you could easily expose IList<IAnimal> that way, but you would risk runtime exceptions if somebody tried to inject another IAnimal implementation into the base class that is not an instance of type Pig. However, in a safe environment, this might be well feasible if it lets you expose your collections as lists and still stick to interfaces.

Author: Categories: C#, Uncategorized, WPF Tags:

Generic Extension Methods to Test INotifyPropertyChanged

November 22nd, 2008

Just two extension methods I wrote in order to simplify testing of classes that implement INotifyPropertyChanged.

The first one just checks that the PropertyChanged event fires once and for the specified property:

 
/// <summary>
/// Checks whether a given action produces a change event for
/// a given property.
/// </summary>
/// <typeparam name="T">A class that implements <see cref="INotifyPropertyChanged"/>.
/// </typeparam>
/// <param name="host">The object that contains the changed property.</param>
/// <param name="changeAction">An action that triggers the
/// <see cref="INotifyPropertyChanged.PropertyChanged"/> event.</param>
/// <param name="propertyName">The name of the changed property, as advertised by the
/// <see cref="INotifyPropertyChanged.PropertyChanged"/> event.</param>
public static void AssertFiresPropertyChangedEvent<T> (this T host, string propertyName,
                                                       Action<T> changeAction)
                                                       where T : INotifyPropertyChanged
{
  bool fired = false;
  
  //register handler with assertion
  PropertyChangedEventHandler handler = (sender, e) =>
    {
      fired = true;
      Assert.AreEqual(propertyName, e.PropertyName);
    };

  //register listener, trigger action, then deregister
  host.PropertyChanged += handler;
  changeAction(host);
  host.PropertyChanged -= handler;

  Assert.IsTrue(fired);
}
 
Now in order to run my test, I can write something like this as long as I’m not having multiple threads that change my object under test:
 
 
//create new user
User user = new User("Tim");

//make sure changing the name raises event
user.AssertFiresPropertyChangedEvent("Name", u => u.Name = "Tom");

 

The second extension method makes sure the event is fired a given number of times for a specified property. Apart from the obvious one (looping a few times), this one has additional use cases:

  • I can test that the event doesn’t fire at all by setting the expected number of events to 0.
  • This method ignores events for other properties, whereas the snippet above fails.

 

/// <summary>
/// Checks whether a given action produces a specified number of property
/// change events for a given property.<br/>
/// This event listener just ignores event for properties other than
/// <paramref name="propertyName"/>.
/// </summary>
/// <typeparam name="T">A class that implements <see cref="INotifyPropertyChanged"/>.
/// </typeparam>
/// <param name="host">The object that contains the changed property.</param>
/// <param name="numberOfEvents">The expected number of change events for
/// the specified property</param>
/// <param name="changeAction">An action that triggers the
/// <see cref="INotifyPropertyChanged.PropertyChanged"/> event.</param>
/// <param name="propertyName">The name of the changed property, as advertised by the
/// <see cref="INotifyPropertyChanged.PropertyChanged"/> event.</param>
public static void AssertPropertyChangedEventCount<T>(this T host, string propertyName,
                                                      int numberOfEvents,
                                                      Action<T> changeAction)
                                                      where T : INotifyPropertyChanged
{
  int eventCount = 0;

  //register handler with assertion
  PropertyChangedEventHandler handler = (sender, e) =>
    {
      //increment if the event refers to the tested property
      if (e.PropertyName == propertyName) eventCount++;
    };

  //register handler, trigger action, then deregister
  host.PropertyChanged += handler;
  changeAction(host);
  host.PropertyChanged -= handler;

  //compare counted events with expected number
  Assert.AreEqual(numberOfEvents, eventCount);
}

 

Update:

If you want to test a full set of properties of a class at once, check out Josh Twist’s ClassTester: This handy little library simplifies things remarkably when it comes to testing complete classes or even assemblies.

Author: Categories: C#, Testing Tags:

Property declaration snippets for ReSharper

March 21st, 2008

Automatic properties in .NET 3.5 are a nice thing, but they are out of the equation if you want to take advantage of the almighty INotifyPropertyChanged interface which plays a crucial role in WPF. Here’s a set of ReSharper snippets that simplify interface implementation and property declaration.

Event Declaration

The first snippet just prints out an interface implementation and adds some additional value to it, including a runtime check of property names in Debug builds (credits go to Josh Smith for this one). Just type inpc to print out this statement:

#region INotifyPropertyChanged event

///<summary>
///Occurs when a property value changes.
///</summary>
public event PropertyChangedEventHandler PropertyChanged;


/// <summary>
/// Raises the <see cref="PropertyChanged"/> event for
/// a given property.
/// </summary>
/// <param name="propertyName">The name of the changed property.</param>
protected void OnPropertyChanged(string propertyName)
{
  //validate the property name in debug builds
  VerifyProperty(propertyName);

  if (PropertyChanged != null)
  {
    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
  }
}


/// <summary>
/// Verifies whether the current class provides a property with a given
/// name. This method is only invoked in debug builds, and results in
/// a runtime exception if the <see cref="OnPropertyChanged"/> method
/// is being invoked with an invalid property name. This may happen if
/// a property's name was changed but not the parameter of the property's
/// invocation of <see cref="OnPropertyChanged"/>.
/// </summary>
/// <param name="propertyName">The name of the changed property.</param>
[Conditional("DEBUG")]
private void VerifyProperty(string propertyName)
{
  Type type = this.GetType();

  //look for a *public* property with the specified name
  PropertyInfo pi = type.GetProperty(propertyName);
  if (pi == null)
  {
    //there is no matching property - notify the developer
    string msg = "OnPropertyChanged was invoked with invalid property name {0}: ";
    msg += "{0} is not a public property of {1}.";
    msg = String.Format(msg, propertyName, type.FullName);
    Debug.Fail(msg);
  }
}

#endregion

 

…and don’t forget to declare the INotifyPropertyChanged implementation. The snippet won’t do that for you:

public class Class1 : INotifyPropertyChanged

 

Property Declaration

The second snippet (shortcut is pcp) simplifies the declaration of a given property for you. You can define property name, type, default value and a description summary. The generated code for a sample property looks like this:

#region UserId

/// <summary>
/// The numeric ID of the user. Defaults to null.
/// </summary>
private int? userId = null;


/// <summary>
/// The numeric ID of the user. Defaults to null.
/// </summary>
public int? UserId
{
  get { return userId; }
  set
  {
    //ignore if values are equal
    if (value == userId) return;

    userId = value;
    OnPropertyChanged("UserId");
  }
}

#endregion

 

Grab the snippet here: Download

Author: Categories: C#, ReSharper, WPF Tags: , ,