Обновление переменной экземпляра с помощью другого метода набора переменных экземпляра - PullRequest
0 голосов
/ 03 ноября 2019

У меня проблема с домашним заданием. У меня есть переменная цена экземпляра, которая должна иметь метод get и метод set. У меня есть эта ценовая переменная, рассчитанная и назначенная через конструктор. Я заметил, что если вы измените значение ширины или высоты на другое число в Main, переменная цены не изменится. Я добавил updatePrice() метод, который будет работать, если явно вызываться в Main, но хотел бы, чтобы он реализовывался автоматически с помощью методов установки высоты / ширины. Я не могу заставить его работать прямо сейчас.

Явный вызов updatePrice() после изменения переменной ширины, которая работает.

using System;
using static System.Console;

class Photo
{
    private int width { get; set; }
    private int height { get; set; }
    protected double price;

    public int Width {
        get
        {
            return width;
        }
        set
        {
            updatePrice(value, height);
            width = value;
        }
    }

    public int Height {
        get
        {
            return height;
        }
        set
        {
            updatePrice(width, value);
            height = value;
        }
    }

    public Photo(int width, int height)
    {
        this.width = width;
        this.height = height;
        if (width == 8 && height == 10)
            price = 3.99;
        else if (width == 10 && height == 12)
            price = 5.99;
        else
            price = 9.99;
    }

    public virtual double Price
    {
        get
        {
            return price;
        }
    }

    public String ToString()
    {
        return GetType() + " with a width of " + width + " and a height of " + height +
            " with a base price of " + Price.ToString("C2");
    }

    // used to be updatePrice() w/ no parameters
    public void updatePrice(int width, int height)
    {
        if (width == 8 && height == 10)
            price = 3.99;
        else if (width == 10 && height == 12)
            price = 5.99;
        else
            price = 9.99;
    }

    static void Main()
    {
        Photo photo = new Photo(10, 12);

        WriteLine(photo.ToString());
        photo.height = 4;
        // updatePrice();
        WriteLine(photo.ToString());
    }
}

Фотография шириной 10 и высотой 12 с базовой ценой 5,99 долларов США // изменить высоту на 4 Фотография шириной 10 и высотой 4 с базовой ценой 5,99 долларов США // цена должна быть $ 9,99

Ответы [ 2 ]

1 голос
/ 03 ноября 2019

Вот ваш код, измененный, как рекомендовано в моем комментарии к вопросу, с updatePrice, помеченным как защищенный виртуальный, чтобы разрешить полиморфизм, добавлено .Name в ToString, и я удалил бесполезные средства доступа к закрытым полям:

class Photo
{

    private int width;
    private int height;
    protected double price;

    public int Width {
        get
        {
            return width;
        }
        set
        {
            width = value;
            updatePrice();
        }
    }

    public int Height {
        get
        {
            return height;
        }
        set
        {
            height = value;
            updatePrice();
        }
    }

    public Photo(int width, int height)
    {
        this.width = width;
        this.height = height;
        updatePrice();
    }

    public virtual double Price
    {
        get
        {
            return price;
        }
    }

    public override string ToString()
    {
        return GetType().Name + 
               " with a width of " + width + 
               " and a height of " + height +
               " with a base price of " + Price.ToString("C2");
    }

    protected virtual void updatePrice()
    {
        if (width == 8 && height == 10)
            price = 3.99;
        else if (width == 10 && height == 12)
            price = 5.99;
        else
            price = 9.99;
    }

}

Так что вам не нужно вызывать updatePrice извне:

static void Main()
{
    Photo photo = new Photo(10, 12);

    WriteLine(photo.ToString());
    photo.height = 4;
    WriteLine(photo.ToString());
}
1 голос
/ 03 ноября 2019

Вместо обновления цены динамически вычисляйте цену в свойстве Price. Таким образом, вы уверены, что он всегда отражает текущее состояние.

public virtual double Price
{
    get
    {
        if (width == 8 && height == 10) return 3.99;
        if (width == 10 && height == 12) return 5.99;
        return 9.99;
    }
}

Я только что сделал этот тест скорости со свойством, как указано выше:

var stopWatch = new Stopwatch();
stopWatch.Start();
for (int i = 0; i < 1_000_000; i++) {
    photo.Height = 4;
    double price = photo.Price;
    photo.Height = 10;
    price = photo.Price;
}
stopWatch.Stop();
Console.WriteLine("Elapsed ms: " + stopWatch.ElapsedMilliseconds);

Обратите внимание, что он вычисляетцена в 2 миллиона раз. Выполнение занимает 67 мс! Поэтому не стоит пытаться оптимизировать этот расчет. Вы экономите всего несколько наносекунд. Но помещение вычисления в свойство упрощает ваш код и делает его более надежным.


Обратите также внимание, что вы должны переопределить существующий метод ToString, унаследованный от object.

public override string ToString()
{
    return $"{GetType()}: width = {width}, height = {height}, base price = {Price:C2}";
}

Затем вы можете распечатать фотографию с помощью

WriteLine(photo);

, так как WriteLine автоматически использует этот метод сейчас. Я также использовал строковую интерполяцию. Это более читабельно, чем конкатенация строк.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...