Elegantly handle duplicate property code in C #

Language shortcut

public string Code { get; set; } 

retains a bit of input when defining trivial properties in C #.

However, I find that I am writing a very repeating, not-quite-trivial property code that still follows a clear pattern, for example.

 public string Code { get { return code; } set { if (code != value) { code = value; NotifyPropertyChanged("Code"); } } } 

I can, of course, define a Visual Studio fragment to reduce input. However, if I need to add something to my template, I need to go back and modify the existing code a bit.

Is there a more elegant approach? Is a snippet the best way?

UPDATE:

As a quick improvement, I edited now (after backing up)

C: \ Program Files \ Microsoft Visual Studio 10.0 \ V # \ Snippets \ 1033 \ Refactoring \ EncapsulateField.snippet

(path for VS 2010)

to reflect my current template. Now the built-in refactoring tool uses my template to create a property from a field. Disadvantages: a global change for Visual Studio, cannot retroactively modify existing property code.

+6
c # properties visual-studio
source share
8 answers

This is known as Aspect Oriented Programming (AOP).

Scott Hansel recently did an interview with LinFu creator Philippe Laureano on the subject. ( link )

There are many AOP tools available depending on your needs.

And finally, some implementations of the INotifyPropertyChanged class using the above tools:

Update 2013: from this original answer, I came across another solution that makes everything I need very easy.

PropertyChanged.Fody (formerly NotifyPropertyWeaver) is an IL code compiler that will automatically insert the changed property code for you. This is now my preferred solution for INotifyPropertyChanged.

+7
source share

That's what I mocked as an exercise. Originally inspired by Jon Skeet blog post .

 public static class ObjectExtensions { public static string GetPropertyNameAndValue<T>(this T obj, out object value) { System.Reflection.PropertyInfo[] objGetTypeGetProperties = obj.GetType().GetProperties(); if(objGetTypeGetProperties.Length == 1) { value = objGetTypeGetProperties[0].GetValue(obj, null); return objGetTypeGetProperties[0].Name; } else throw new ArgumentException("object must contain one property"); } } class Whatever { protected void ChangeProperty<T>(object property, T newValue, Action change) { object value; var name = property.GetPropertyNameAndValue(out value); if(value == null && newValue != null || value != null && !value.Equals(newValue)) { change(); OnPropertyChanged(name); } } private string m_Title; public string Title { get { return m_Title; } set {ChangeProperty( new { Title }, //This is used to dynamically retrieve the property name and value value, // new value () => m_Title = value); //lambda to change the value } } } 

This is the best I could think of. Slow performance at runtime can be quite high, but I have not tested it.

A bit about this explanation. new { Title } creates an anonymous object and because of the project (introduced in .NET 3.5), the newly created object has one Title property and a value that is the value of the Title property of the original object.

GetPropertyNameAndValue is a function that does all the interesting work — it extracts the name and value of a property from an anonymous object. ChangeProperty then performs an equality check and calls the lambda, which actually changes the property, and also calls NotifyPropertyChanged .

Alternatively, you can simply do this snipppp:

 <?xml version="1.0" encoding="utf-8" ?> <CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet"> <CodeSnippet Format="1.0.0"> <Header> <Title>propfullinotify</Title> <Shortcut>propfullinotify</Shortcut> <Description>Code snippet for property and backing field with INotifyPropertyChanged</Description> <Author>Microsoft Corporation</Author> <SnippetTypes> <SnippetType>Expansion</SnippetType> </SnippetTypes> </Header> <Snippet> <Declarations> <Literal> <ID>type</ID> <ToolTip>Property type</ToolTip> <Default>int</Default> </Literal> <Literal> <ID>property</ID> <ToolTip>Property name</ToolTip> <Default>MyProperty</Default> </Literal> <Literal> <ID>field</ID> <ToolTip>The variable backing this property</ToolTip> <Default>myVar</Default> </Literal> </Declarations> <Code Language="csharp"> <![CDATA[private $type$ $field$; public $type$ $property$ { get { return $field$;} set { if ($field$ != value) { $field$ = value; if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("$property$")); } } } $end$]]> </Code> </Snippet> </CodeSnippet> </CodeSnippets> 
+3
source share

I did not do this myself, but I saw that the dependency injection infrastructure was used for this particular task.

Goes and googles

Ahaha!

It seems using the Unity DI framework , you can introduce INotifyPropertyChanged into the auto property. Take a look at this wonderful blog post: http://shecht.wordpress.com/2009/12/12/inotifypropertychanged-with-unity-interception-aop/

This reminds me of the recent HanselMinutes, where Scott is talking to a guy on aspects of Oriented Programming (AOP), where this type of injection is very common.

+2
source share

I hate writing this code!

In the past, to solve this problem, I used a code generator to create a partial class with property definitions.

+1
source share

Take a look at NotifyPropertyWeaver: https://github.com/SimonCropp/NotifyPropertyWeaver

+1
source share

Thank you all for your answers. I got helpful answers. However, after a little research, I came to the conclusion that the best answer (at least for me and the way to develop software) is to model classes in Visual Studio and use T4 to generate partial classes that implement the code property.

See http://msdn.microsoft.com/en-us/library/ee329480.aspx

0
source share

very common picture. Snippet is fine, but boy, it wouldn’t be great if MS created some kind of syntactic sugar for notifications about changes in car properties ....

Something like....

 public string Code { get; setwithnotify; } 

That would really be very nice.

-one
source share

To answer the general question about re-code, and not just in the case of notification of a property change:

Of course. This is ideal for macros.

Oh wait. C # has no macros. Of course, macros are evil and are not the best solution for any programming problem.

If you do not introduce a preprocessor to your assembly.

-6
source share

All Articles