Stringa, tu mi hai provocato… E io te distruggo

De gustibus tutta la vita, però io le stringhe cablate nel codice non le sopporto proprio. Una vita intera a tentare di evitarla e poi ti arriva MVVM che, a botte di implementazioni di INotifyPropertyChanged ti fa spuntare come funghi “robe” di questo tipo:

    private string emailAddress;
    /// <summary>
    /// Customer  e-mail address
    /// </summary>
    public string EmailAddress
    {
        get
        {
            return this.emailAddress;
        }
        set
        {
            this.emailAddress = value;
            RaisePropertyChanged("EmailAddress");
        }
    }

Terribile, nevvero? “Ispirandomi” ad un tip che scrissi per UGIdotNET un paio di anni addietro, mi son detto: perché non usare la stessa tecnica “lambda based” per risolvere il problema una volta per tutte? E quindi:

    public static class ReflectionHelper<T>
    {
        public static string GetPropertyName(Expression<Func<T, object>> subSelector)
        {
            if (subSelector.Body is MemberExpression)
            {
                return ((subSelector.Body as MemberExpression).Member as PropertyInfo).Name;
            }
            else
            {
                var memberPropertyAccessor = ((subSelector.Body as UnaryExpression).Operand.GetType().GetProperty("Member"));
                var memberPropertyValue = memberPropertyAccessor.GetValue((subSelector.Body as UnaryExpression).Operand, null);
                var namePropertyAccessor = memberPropertyValue.GetType().GetProperty("Name");
                var propertyName = (string)namePropertyAccessor.GetValue(memberPropertyValue, null);
                return propertyName;
            }
        }
    }

Che significa poter scrivere il primo snippet così:

   private string emailAddress;
   /// <summary>
   /// Customer  e-mail address
   /// </summary>
   public string EmailAddress
   {
       get
       {
           return this.emailAddress;
       }
       set
       {
           this.emailAddress = value;
           RaisePropertyChanged(
                   ReflectionHelper<CustomerDetailViewModel>.GetPropertyName(vm => vm.EmailAddress)
               );
       }
   }

Non so voi, ma IMVHO il solo fatto di poter fare refactoring in modo “sicuro” ha giustificato i 10 minuti spesi a scrivere la funziona helper. E’ una lambda: leggere attentamente le avvertenze, usare con cautela.

P.S.: giusto il tempo di portare l’implementazione dallo stato di “funziona” a quello di “fa meno schifo a leggerla” nonché di vedere che i test continuano a dare luce verde, e la infilo in NSK ad imperitura memoria

P.P.S.: Buona anche l’idea di “infilare” la funzione helper in un eventuale classe ViewModelBase, così da evitare la prima parte della invocazione e rendere il codice meno prolisso

Technorati Tag: ,,,
«giugno»
domlunmarmergiovensab
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910