Monday 29 June 2015

Efficient and defensive code snippets

It has been said that dequehead's INPC bindable property code snippets are handy, but they produce ugly code. As a seasoned STL user, that saddens him.

Here is an example of offending code:

private float _ChickensPerFox;
public float ChickensPerFox { get { return this._ChickensPerFox; } set { this.SetProperty(ref this._ChickensPerFox, value); } }
Using the snippet the required keystrokes are b p [tab] [tab] "float" [tab] "ChickensPerFox" [tab]. Pretty cheap; normally you'd have to enter the backing field and property names seperately, remembering to capitalise only the property. Even so, some say it is too ugly to live with.

But is it really ugly? Actually I think not. If you are going to use a property instead of a field it is probably because you don't want to use the field even when it is in scope. The leading underscore puts it after the property in auto-complete, whereas a lower-case first letter (the usual convention) makes the field the 'default' choice for auto-complete. Dangerous.

The original inspiration came from Microsoft's C++ Standard Template Library implementation and its almost impenetrable codebase which makes extensive use of this clause on page 20-ish of the working draft specification:

    (3.1) — Each identifier that contains a double underscore __ or begins with an underscore followed by an uppercase letter is reserved to the implementation for any use.
When I say "extensive" and "impenetrable", I mean it. Check this out
template<class _InIt1,
 class _InIt2,
 class _Pr> inline
_SCL_INSECURE_DEPRECATE
 pair<_InIt1, _InIt2>
  _Mismatch2(_InIt1 _First1, _InIt1 _Last1,
   _InIt2 _First2, _Pr _Pred, false_type)
 { // return [_First1, _Last1)/[_First2, ...) mismatch, unchecked input
 return (_Mismatch(_First1, _Last1,
  _First2, _Pred));
 }
So I feel reasonably comfortable if people have to deal with some private fields that look like _ChickensPerFox, and I am very comfortable that they are less likely to use them by accident.

While he is at it, dequehead decides to share some more snippets

Here's a similar one, but it adds a handler for change notifications. Comes out like this:

private float _HeadsPerChicken;
public float HeadsPerChicken
{
    get { return this._HeadsPerChicken; }
    set
    {
        if (this.SetProperty(ref this._HeadsPerChicken, value))
        {
            System.Diagnostics.Debug.WriteLine("Chickens have {1} heads", value);
        }
    }
}
There is a corresponding pair for Dependency Properties:
public String ChickenName { get { return (String)GetValue(ChickenNameProperty); } set { SetValue(ChickenNameProperty, value); } }
public static readonly DependencyProperty ChickenNameProperty = DependencyProperty.Register("ChickenName", typeof(String), typeof(MainPage), new PropertyMetadata(default(String)));
public String FoxName { get { return (String)GetValue(FoxNameProperty); } set { SetValue(FoxNameProperty, value); } }
public static readonly DependencyProperty FoxNameProperty = DependencyProperty.Register("FoxName", typeof(String), typeof(MainPage), new PropertyMetadata(default(String), (s, e) =>
{
    var d = s as MainPage;
    var new_value = (String)e.NewValue;

    d.Background = new SolidColorBrush(Windows.UI.Colors.Red);
}));

And lastly an observable collection snippet, which comes out like this:

private readonly ObservableCollection<ChickenModel> _ChickenModels = new ObservableCollection<ChickenModel>();
public ObservableCollection<ChickenModel> ChickenModels { get { return _ChickenModels; } }

The snippets are all on GitHub. There are loads of other MVVM snippets in dequehead's arsenal, it's worth asking. If he has what you need he'll tidy it up an post it.

No comments:

Post a Comment