skm
skm

Reputation: 5659

C# How to pass Properties in a generic way without Reflections?

Currently I have three properties in class MyClassOne. The number of properties may increase in future. Whenever any of the property changes, I need to call a method called SavePropertyToFile() which is responsible to set the corresponding property (AnotherPropertyOne, AnotherPropertyTwo or AnotherPropertyThree) of another class.

My sample code (which is of course not working) is below:

Class MyClassOne
{
        public bool PropertyOne
        {
            get => _propertyOne;
            set
            {
                if (_propertyOne == value)
                    return;

                _propertyOne = value;
                SavePropertyToFile(value, MyAnotherClass.AnotherPropertyOne); //<------------------
                NotifyOfPropertyChange(() => _propertyOne);
            }
        }


        public bool PropertyTwo
        {
            get => _propertyTwo;
            set
            {
                if (_propertyTwo == value)
                    return;

                _propertyTwo = value;
                SavePropertyToFile(value, MyAnotherClass.AnotherPropertyTwo); //<------------------
                NotifyOfPropertyChange(() => _propertyTwo);
            }
        }
        
        public bool PropertyThree
        {
            get => _propertyThree;
            set
            {
                if (_propertyThree == value)
                    return;

                _propertyThree = value;
                SavePropertyToFile(value, MyAnotherClass.AnotherPropertyThree); //<------------------
                NotifyOfPropertyChange(() => _propertyThree);
            }
        }       

        SavePropertyToFile(bool value, TProperty myPropertyOfAnotherClass)
        {
            myPropertyOfAnotherClass = value;
            
            // Some more lines of Code
            
            RefreshProgram();
        }
}  

In the code above, I need to find a way so that I can parse the correct property of AnotherClass. I already had a look at this another SO question, but I am not able to apply any of the answer for my case.

How can I parse different properties to a method?

Update: As per the suggestions in the comments, I have tried to use "Nathan Baulch" answer's option-2 but then I getting warning/error wiggly line as shown in the screenshot below:

enter image description here

Upvotes: 1

Views: 87

Answers (1)

JonasH
JonasH

Reputation: 36521

If the idea is to make several classes use the same property, my approach is to wrap the values in a class:

public class Changeable<T> : INotifyPropertyChanged
{
    private T currentValue;

    public Changeable(T initialValue) => currentValue = initialValue;

    public T Value
    {
        get => currentValue;
        set
        {
            if (!EqualityComparer<T>.Default.Equals(currentValue, value))
            {
                this.currentValue = value;
                Changed?.Invoke(this, value);
                OnPropertyChanged(nameof(Value));
            }
        }
    }

    public event EventHandler<T> Changed;
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) 
        => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

You can then just let both classes use the same actual object. This approach can also be used to cut down on boilerplate for wpf, instead of declaring getters and setters you can just write:

public Changeable<bool> MyProperty {get;} => new (false);

Just remember to update the binding: {Binding MyProperty.Value}

You can also write various extensions. For example if you want to update one property whenever some other property updates:

MyProperty.BindTo(MyIntProperty, intValue => intValue > 0);

So whenever MyIntProperty changes sign, the MyProperty would be updated and raise its changed event. I'm not going to include all the code behind this, since it is fairly large, but I hope you get the idea. This approach makes it possible to link various UI values in a convenient way, but it can also make the code more difficult to understand and debug, so some caution is advised.

Upvotes: 1

Related Questions