Aviv Cohn
Aviv Cohn

Reputation: 17203

Is there a way for a property to set its backing value?

I have a property, and I want it to set another property whenever it's being set. For example:

    private double Bpm
    {
        set
        {
            <myself> = value;
            _bps = <myself> / 60;
        }
        get
        {
            return <myself>;
        }
    }

What I actually did is the following, because I couldn't find another way:

    private double _bpm;
    private double _bps;

    private double Bpm
    {
        set
        {
            _bpm = value;
            _bps = _bpm / 60;
        }
        get
        {
            return _bpm;
        }
    }

I find it not elegant, having two private members Bpm and _bpm. I can also have a SetBpm method, but I want to know if this is achievable with properties.

Upvotes: 1

Views: 130

Answers (3)

Jon Skeet
Jon Skeet

Reputation: 1500873

A property is just a pair of methods, really - and if you use an automatically-implemented property, the compiler implements them for you and creates a field. You want one field - because you've only got one real value, and two views on it - so you can either get the compiler to create that field for you automatically by using an automatically-implemented property, or you can declare it yourself. I'd use an automatically-implemented property, personally. Then you calculate the other property based on the original. You can either make that a read-only property, or make it read-write.

For example, as a read-only version:

public double BeatsPerSecond { get; set; }
public double BeatsPerMinute { get { return BeatsPerSecond * 60; } }

Or in C# 6:

public double BeatsPerSecond { get; set; }
public double BeatsPerMinute => BeatsPerSecond * 60;

For a read-write version:

public double BeatsPerSecond { get; set; }
public double BeatsPerMinute
{
    get { return BeatsPerSecond * 60; }
    set { BeatsPerSecond = value / 60; }
}

You could decide to make BeatsPerMinute the "stored" one instead, should you wish, and just change the property calculation.

Upvotes: 10

shA.t
shA.t

Reputation: 16968

Actually using properties are in public mode, so you can change your property to a value like below:

private double Bpm;

private double Bps
{
    get 
    {
        return Bpm / 60;
    }
}

With thanks to @Farhad Jabiyev.

Upvotes: 2

Douglas
Douglas

Reputation: 54887

My preferred approach would be to expose two public properties that update each other's backing fields. If your properties are read more frequently than they are updated, this would avoid repeatedly performing a multiplication or division operation on each read.

private double _bpm;
private double _bps;

private double Bpm
{
    get
    {
        return _bpm;
    }
    set
    {
        _bpm = value;
        _bps = value / 60;
    }
}

private double Bps
{
    get
    {
        return _bps;
    }
    set
    {
        _bps = value;
        _bpm = value * 60;
    }
}

Upvotes: 2

Related Questions