Хобрук: Ваш путь к мастерству в программировании

Альтернатива написанию многих операторов if?

Вот мой метод:

private void ConvertValues()  
{  
    txtResult.Text = angles[cmbUnits1.SelectedIndex];  
    double value1 = Convert.ToDouble(txtValue1.Text);  
    double value2 = Convert.ToDouble(txtValue2.Text);  
    int unit1 = cmbUnits1.SelectedIndex;  
}

То, что я хочу, чтобы метод сделал, это получить выбранный из ComboBoxes и проверить значения. Но я хочу знать, есть ли альтернатива этому:

if( angles[cmbUnits1.SelectedIndex].Equals("Degrees") && 
    angles[cmbUnits2.SelectedIndex].Equals("Radians")) {  
    ...  
}

Кстати, я делаю что-то вроде конвертера величин, поэтому у меня будут сечения, отличные от углов. Поэтому мне нужно какое-то перечисление, интерфейс, абстрактный класс или класс, который я могу реализовать. Может быть, класс с именем Unit? Таким образом, я могу создавать новые объекты, такие как Unit degrees = new Unit(Units.Angle), с единицами в качестве перечисления. Или просто Unit sqrMillimeters = new Unit("Area");?

20.12.2009

  • Взгляните на синтаксис уценки, чтобы в следующий раз опубликовать ответ или вопрос на SO: stackoverflow.com/editing-help 20.12.2009

Ответы:


1

Конечно, полиморфизм. Каждый раз, когда вы видите длинные операторы switch или конструкции if/then/else, их всегда можно обработать с помощью полиморфизма и фабрик. В вашем случае я бы предположил, что интерфейс ITemperatureConverter с конкретными реализациями для градусов Фаренгейта, Цельсия, Кельвина и Ренкина подойдет.

ОБНОВИТЬ:

Если вы обнаружите, что повторяете эту логику, почему бы не использовать лучшую абстракцию для Angle, чем double?

Если вы пишете на объектно-ориентированном языке, хорошей идеей будет подняться выше примитивов (например, double и, да, string), чтобы инкапсулировать поведение в объекты.

Я бы подумал о классе Angle, который цеплялся бы за значение и возвращал бы его как любую меру, которую вы хотите.

Вот один из способов сделать это на Java. Я оставлю вам перевод на C# и все остальное.

package angles;

public class Angle
{
    private double value;
    private AngleUnit units;

    public Angle()
    {
        this(0.0, AngleUnit.RADIANS);
    }

    public Angle(double value)
    {
        this(value, AngleUnit.RADIANS);
    }

    public Angle(double value, AngleUnit units)
    {
        this.value = value;
        this.units = units;
    }

    public double getValue()
    {
        return value;
    }

    public AngleUnit getUnits()
    {
        return units;
    }

    public Angle convert(AngleUnit newUnits)
    {
        Angle newAngle = null;

        if (this.units.equals(newUnits))
        {
            return this;
        }

        return newAngle;
    }
}

package angles;

public interface AngleConverter
{
    Angle convert(Angle angle, AngleUnit to);
}

package angles;

public enum AngleUnit
{
    DEGREES, RADIANS, GRADIANS;
}

package angles;

import java.util.HashMap;
import java.util.Map;

public class DegreeConverter implements AngleConverter
{
    private final Map<AngleUnit, Double> factors;

    public DegreeConverter(Map<AngleUnit, Double> factors)
    {
        this.factors = new HashMap<AngleUnit, Double>();
        this.factors.put(AngleUnit.DEGREES, 1.0);
        this.factors.put(AngleUnit.RADIANS, Math.PI/180.0);
        this.factors.put(AngleUnit.GRADIANS, 100.0/90.);
    }

    public Angle convert(Angle angle, AngleUnit to)
    {
        assert angle != null && to != null;

        return new Angle(angle.getValue()*this.factors.get(to), to);
    }
}
20.12.2009
  • ‹/сарказм› (Вот, исправил это для вас.) 20.12.2009
  • Я думаю, что количество - это угол, а не температура :-), но логика идентична 20.12.2009
  • @peter, точно. Я не читал его достаточно внимательно, но пример все еще актуален. Думаю, мне следовало указать градусы, радианы, градианы, минуты и т. д. 21.12.2009

  • 2

    double UnitToFactor(string unit) { returns 1 for radians, pi/180 for degrees, etc }

    тогда

    ratio = UnitToFactor(unit1) / UnitToFactor(unit2);

    и dest = src*ratio

    Таким образом, вместо N^2 операторов if() у вас будет только N.

    20.12.2009

    3

    Можно ли вместо этого написать оператор switch?

    switch (something)
    {
      case "degrees" : do work
      ...etc
    }
    
    20.12.2009
  • Возможно, но мне пришлось бы иметь вложенные операторы switch. Не сильно отличается от if elseif 21.12.2009

  • 4

    Как насчет комбинации событий SelectedIndexChanged/SelectedValueChanged и некоторого полиморфизма?

    20.12.2009

    5

    Вы можете объединить обе строки ("DegreesRadians") и вызвать метод под названием "DegreesRadians" через Reflection:

    MethodInfo theMethod = thisType.GetMethod(methodName);
    theMethod.Invoke(this, parameters);
    

    Где methodName — это объединенные строки (возможно, с дополнительной информацией, например, «convert» + unit1 + «2» + unit2, например, «convertDegrees2Radians»), а параметры — это массив, содержащий оба значения.

    20.12.2009
    Новые материалы

    Основы принципов S.O.L.I.D, Javascript, Git и NoSQL
    каковы принципы S.O.L.I.D? Принципы SOLID призваны помочь разработчикам создавать надежные, удобные в сопровождении приложения. мы видим пять ключевых принципов. Принципы SOLID были разработаны..

    Как настроить Selenium в проекте Angular
    Угловой | Селен Как настроить Selenium в проекте Angular Держите свое приложение Angular и тесты Selenium в одной рабочей области и запускайте их с помощью Mocha. В этой статье мы..

    Аргументы прогрессивного улучшения почти всегда упускают суть
    В наши дни в кругах веб-разработчиков много болтают о Progressive Enhancement — PE, но на самом деле почти все аргументы с обеих сторон упускают самую фундаментальную причину, по которой PE..

    Введение в Джанго Фреймворк
    Схема «работать умно, а не усердно» В этой и последующих статьях я познакомлю вас с тем, что такое фреймворк Django и как создать свое первое приложение с помощью простых и понятных шагов, а..

    Настольный ПК как «одно кольцо, чтобы править всеми» домашних компьютеров
    Вид после 9 месяцев использования С настольных компьютеров все началось, но в какой-то момент они стали «серверами», и мы все перешли на ноутбуки. В прошлом году я столкнулся с идеей настольных..

    Расширенные методы безопасности для VueJS: реализация аутентификации без пароля
    Руководство, которое поможет вам создавать безопасные приложения в долгосрочной перспективе Безопасность приложений часто упускается из виду в процессе разработки, потому что основная..

    стройный-i18следующий
    Представляем стройную оболочку для i18next. Эта библиотека, основанная на i18next, заключает экземпляр i18next в хранилище svelte и отслеживает события i18next, такие как languageChanged,..