6

We are doing alot of INotifyPropertyChanged implementation in our View Models and quite frankly are getting tired of having to fire the property changed events explicitly in our code for both inconvenience and aesthetic reasons.

I want to put an extension on the setter of our property, making the resulting code look like:

public string LazyAccessor
{
  get;
  set.notify();
}

Is there a way to do this? Can we invent one if there isn't?

Abdul Rahman
  • 2,097
  • 4
  • 28
  • 36
Hank
  • 61
  • 1
  • 2

7 Answers7

4

Check out NotifyPropertyWeaver. This will modify your code during the build process to have your properties implement the INotifyPropertyChanged pattern.

This is available as a Visual Studio Extension

cadrell0
  • 17,109
  • 5
  • 51
  • 69
  • I take it this was either a precursor to AOP with stuff like PostSharp or they didn't know PostSharp existed? – Mike Perrenoud Oct 19 '12 at 14:56
  • @BigM I'm not really sure about the details of how either work. I know they both use IL Weaving, so they are similar in concept. The reason I use NotifyPropertyWeaver is you do not need to clutter your code with attributes. – cadrell0 Oct 19 '12 at 15:07
  • Good reason to use that solution. PostSharp is ***very*** generic and this is suited to solve **one** pain point, it's certainly going to be more concise! – Mike Perrenoud Oct 19 '12 at 15:12
  • @cadrell0 i looked at postsharp and found it wanting. here is my reasoning http://simoncropp.com/attemptingtosolvetheinotifypropertychangedproblem – Simon Oct 20 '12 at 03:56
3

Aspect oriented programming could be solution of your problem.

See Aspect Oriented Programming in C#. And some examples here: http://www.codeproject.com/Articles/337564/Aspect-Oriented-Programming-Using-Csharp-and-PostS

Your "set.notify()" could work with some Reflection, but I don´t think this would be good solution and you will still need to implement getter and setter.

Community
  • 1
  • 1
Ondra
  • 1,619
  • 13
  • 27
3

Extension methods can only be added to types. The getters and setters on automatic properties are converted into methods with backing variables by the compiler, so there is no way to put an extension method on them.

goric
  • 11,491
  • 7
  • 53
  • 69
2

Is there a way to do this?

No, there isn't, not like you posted. Extension methods operate on types, not getters or setters.

Can we invent one if there isn't?

That would require changes to the C# specification - not a likely thing to happen.

There are other approaches that you can take to ease this - using a base class with a method that will make the boiler plate calls for you for example.

Oded
  • 489,969
  • 99
  • 883
  • 1,009
  • Another interesting approach. Could you look at my answer and see if that's viable too? I value your opinion as your reputation precedes you. Maybe it's too heavy? – Mike Perrenoud Oct 19 '12 at 14:55
0

They didn't make it into 4.0, but are rumored to be included in 5.0.

I found this approach helpful.

jeuton
  • 543
  • 3
  • 7
0

You couldn't do it on the set itself. That is an action. You might however be able to do this:

public static class extensions()
{
  public static NotifyAccessorSet(this string value) { some code }
}

public class SomeClass()
{
  .....
  private string mAccessor;

  public string LazyAccessor{
     get { return mAccessor; }
     set { mAccessor = value; mAccessor.NotifyAccessorSet(); }
  }

}

It's somewhat off the top of my head and keep in mind that the extension method would apply to all types string so you might want to implement your own return type and apply the extension method to it. Return that type then from lazyaccessor.

DRobertE
  • 3,478
  • 3
  • 26
  • 43
  • I am not sure, but I think to fire NotifyPropertyEvent you need to know the originating object (sender) and property name ("LazyAccessor" in this sample). So your code will make it even more chatty. – Ondra Oct 19 '12 at 15:01
  • You would have the originating object... it would be the "value" in the NotifyAccessorSet function. In any case... just a suggestion. this approach would implement an additional function call, this would just provide a way to implement the notification in the set method. – DRobertE Oct 19 '12 at 15:21
0

you can emulate a 'property-like' behavior without calling the event manualy by overriding the conversion operators of a custom generic struct. The following is my solution:

public struct column<TType>
{
    private TType _value;

    private column(TType value) : this()
    {
        _value = value;
    }

    private void Set(TType value)
    {
        // Implement your custom set-behavior...
    }

    private TType Get()
    {
        // Implement your custom get-behavior...
        return _value;
    }

    public override string ToString()
    {
        return _value.ToString();
    }

    public static implicit operator column<TType>(TType p)
    {
        column<TType> column = new column<TType>(p);
        column.Set(p);
        return column;
    }

    public static implicit operator TType(column<TType> p)
    {
        return p.Get();
    }
}

I declare the struct with a generic parameter to avoid from conversion errors. You can use it like this:

public class Test
{
    public column<int> kKey;

    public column<float> dMoney;

    public column<string> cValue;


    public Test()
    {
        kKey   = 42;
        dMoney = 3.1415926f;
        cValue = "May the force be with you!";
    }
}

...I know, the question is outdated but it may help someone in the future.