Suggestion: Generic property patterns in C# to DRY up your code.

Topics: C# Language Design
May 2, 2014 at 11:42 AM
Properties in C# are not very DRY. Unless your application needs fit the canned auto properties pattern your code is bloated with get and set code everywhere and the code is copy paste hell. IDE tools like template expansion of common patterns just mask a deficiency in the language.

I propose a generic property pattern that DRY's up property specification.

A compelling example


We have a view model class that for convienience inherits from our view model base class. We want all properties to follow the INPC pattern of raising INotifiyPropertyChanged when set. There are all sorts of hacks to make this work easier. There are IDE plugins, code weavers, callermembername fixes etc. However it could easily be achieved as below.

Here an extra keyword property declares that the property implementation follows
a specific pattern. The required pattern is specified between angle brackets and the
type and name of the property are declared normally.
class Foo : ViewModelBase {
    public property<INPC> string FirstName = "John";
    public property<INPC> string LastName = "Doe";
    public property<INPC> int Age = 39;
}
The implementation of INPC again uses the property keyword and the body of
the property is similar to what we normally do with properties, ie supply a get
and a set method, except here we can have a property constructor and instance
variables scoped to the property so we don't have name collision with the parent
class.
property INPC<TParent, TProp>
where TParent : ViewModelBase
{
    // Internal data will be scoped only to the
    // property
    TProp _data;

    // Property constructor can be used to initialize
    // internal property scoped data
    INPC(TParent parent, string name, TProp value){
        _data = value;
    }

    // Getter
    T get(TParent parent, string name) {
        return data;
    }
    
    // Getter
    set(TParent parent, string name, TProp value) {
        parent.RaiseAndSetIfChange(ref _data, value, name);
    }
}
I am sure there are plenty edge cases that may make this difficult but I really don't think it is necessary to have code bloated with copy paste get, set code everywhere. A normal declaration of an INPC supporting property takes 7 lines of code.
bool _NeedsSaving;
 public bool NeedsSaving
{
    get { return _NeedsSaving; }
    set { this.RaiseAndSetIfChanged(ref _NeedsSaving, value); }
}
vs
public property<INPC> bool NeedsSaving;
Fixing this problem would make visual code comprehension so much simpler. To go even further you could implement a pattern block. Using the previous example I create a property block where all properties follow the pattern at the head of the block.
class Foo : ViewModelBase {
   public property<INPC> {   
        string FirstName = "John";
        string LastName = "Doe";
        int Age = 39;
    }
}
May 2, 2014 at 3:43 PM
It seems to me that the same thing could also be achieved using attribute-based metaprogramming, except that feature is much more useful, because it's more general.
May 2, 2014 at 4:33 PM
Yes and no. I agree it's more general and would work nicely for this use case. However the main feature of roslyn is the ability to do easy refactoring on the AST and thus one of the main customers of Roslyn will be the IDE team. With a full macro system that becomes much harder and I'd expect major pushback against such a feature. Then again, maybe not! I'm not a compiler expert, just grumpy that my code is ugly.

As well if pattern based properties are implemented as a language feature then it can be tailored so that joe average programmer can write them just like they write classes and lambdas. I suspect any macro feature would require a more advanced understanding.