Propertys mal ganz anders

Wer kennt es nicht? Das nervige anlegen von Backing-Fields für Propertys. Das anschließende Invoken von Änderungen dieser Propertys und den auch noch das setzen von Standardwerten. Da wäre es doch nahe zu Perfekt, wenn dies auch gehen würde ohne dass diese extra Aufwände notwendig sind, nicht wahr? Einen Hinweis vorweg, dieser Code benötigt die bereits erstellte Klasse aus dem Post „PropertyChanged – Komplett und kompakt!„, welches ich am 3. Februar bereits hier veröffentlicht hatte. Ebenfalls sollte bedacht werden, das wiedermal mindestens .NET 3.5 erforderlich ist. Die Erweiterung durch .NET 4.5 ist eher „nett“ als wirklich nötig. 

Aber kommen wir zum Interessanten Teil, den Sourcecode.

public abstract class ExtendedPropertyBase : PropertyChangedBase, IDisposable
{
    private readonly Dictionary<string, object> _propertyValues = new Dictionary<string, object>();

    #region Get

    #if !NET20 && !NET30

    protected T Get<T>(Expression<Func<T>> expression, T defaultValue = default(T))
    {
        return Get(GetPropertyName(expression), defaultValue);
    }

    protected T Get<T>(string propertyName, T defaultValue = default(T))
    {
        return _propertyValues.ContainsKey(propertyName) ? (T) _propertyValues[propertyName] : defaultValue;
    }

    #endif

    #endregion

    #region Set

    #if !NET20 && !NET30

    protected void Set<T>(Expression<Func<T>> expression, T value)
    {
        Set(GetPropertyName(expression), value);
    }

    protected void Set<T>(string propertyName, T value)
    {
        if (_propertyValues.ContainsKey(propertyName))
        {
            if (_propertyValues[propertyName] != null &&
                (_propertyValues[propertyName] ?? new object()).Equals(value))
                return;

            if (value is IComparable)
            {
                if (_propertyValues[propertyName] != ((IComparable) value))
                {
                    _propertyValues[propertyName] = value;
                    OnPropertyChanged(propertyName);
                }
            }
            else
            {
                _propertyValues[propertyName] = value;
                OnPropertyChanged(propertyName);
            }
        }
        else
        {
            _propertyValues.Add(propertyName, value);
            OnPropertyChanged(propertyName);
        }
    }

    #endif

    #if NET45

    protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
    {
        if (Equals(storage, value)) 
            return false;

        storage = value;
        OnPropertyChanged(propertyName);

        return true;
    }

    #endif

    #endregion

    public void Dispose()
    {
        _propertyValues.Clear();
    }
}

Wie hier zu sehen ist, bedient sich diese Klasse bei den Generischen Typen als auch bei unserer Klasse aus meinen ersten Entwickler-Blog-Post. Natürlich ist es auch hier wieder Sinnvoll zu sehen, wie dies ganze nun Funktioniert.

public string SomeProperty 
{
	get { return Get(() => SomeProperty, "Some defualt value"); }
	set { Set(() => SomeProperty, value); }
}

Wie hier zu erkennen nutzen wir direkt die volle Ladung unserer neuen Klasse. Dabei möchte ich anmerken, dass der beim „Get“ gesetzte Standardparameter optional ist und nicht gesetzt werden muss. Sollte dies weggelassen werden, tritt der Standardwert für den Typen ein z.B. bei einen Integer der Wert „0“ bei klassen aber natürlich „NULL“. Auch wird hier immer ein „PropertyChanged“-Event ausgelöst, wenn sich mittels „Set“ der Wert wirklich Ändert (ungleich zum vorherigen Wert) ist. Ich hoffe dass auch diese Klasse seinen nutzen findet und einigen Helfen konnte. Feedback ist natürlich wieder gern gesehen und die Klasse könnt ihr hier herunterladen.