Подтвердить что ты не робот

Как добавить или вычесть два экземпляра одного и того же класса/типа

У меня есть тип, который представляет тип номера. В этом случае я работаю с мегаваттами, поэтому создал тип под названием Megawatt. Я хотел бы иметь возможность работать с этими мегаваттами, как если бы я имел тип Int, Double или любой тип номера С#. Это возможно? Если да, то как это сделать?

Пример:

public class Megawatt{
    public double Value { get; set; }
}

Я хочу иметь возможность сделать это:

var startOfDay = new Megawatts{value=100};
var endOfDay = new Megawatts{value=65};
Megawatt result = startOfDay - endOfDay;

Это возможно с помощью DateTime... вы можете вычесть одно DateTime из другого и получить TimeSpan. Я надеюсь сделать что-то подобное.

4b9b3361

Ответ 1

В дополнение к хорошим ответам, опубликованным до сих пор: вы должны сделать свой тип неизменяемой структурой, а не изменяемым типом значений. Это именно та работа, для которой были созданы неизменные типы значений.

struct Megawatt
{
    private double Value { get; private set; }
    public Megawatt(double value) : this()
    {
        this.Value = value;
    }
    public static Megawatt operator +(Megawatt x, Megawatt y)
    {
        return new Megawatt(x.Value + y.Value);
    }
    public static Megawatt operator -(Megawatt x, Megawatt y)
    {
        return new Megawatt(x.Value - y.Value);
    }
    // unary minus
    public static Megawatt operator -(Megawatt x)
    {
        return new Megawatt(-x.Value);
    }
    public static Megawatt operator *(Megawatt x, double y)
    {
        return new Megawatt(x.Value * y);
    }
    public static Megawatt operator *(double x, Megawatt y)
    {
        return new Megawatt(x * y.Value);
    }
}

И так далее. Обратите внимание, что вы можете добавить два мегаватта, но вы не можете умножить два мегаватт; вы можете умножать мегаватты только на парные.

Вы также можете добавить больше загруженных единиц. Например, вы можете создать тип MegawattHour и тип Hour, а затем сказать, что Megawatt times Hour дает MegawattHour. Вы могли бы также сказать, что есть еще один тип Джоуля, и есть неявное преобразование из MegawattHour в Joule.

Существует ряд языков программирования, которые поддерживают эти виды операций с меньшей детализацией, чем С#; если вы делаете много таких вещей, вы можете посмотреть в F #.

Ответ 2

вы должны написать собственную перегрузку оператора:

:

   public static Megawatt operator +(Megawatt c1, Megawatt c2) 
   {
      return new Megawatt(c1.value+ c2.value);
   }

Ответ 3

Это называется перегрузкой оператора. Предлагаю вам прочитать эту статью:

http://msdn.microsoft.com/en-us/library/aa288467(v=vs.71).aspx

Это учебник по этому процессу. В основном вы изменяете значение оператора - для этих типов.

В качестве примера (украденного из ссылки)

public static Megawatt operator -(Megawatt c1, Megawatt c2) 
{
  // do whatever you want here
}

И таким образом ваш знак минус теперь может вычитать MegaWatts

Вы можете сделать это для любого типа или комбинации типов. Вы даже можете вернуть еще третий тип, если хотите. Многие языки поддерживают эту концепцию и ее весьма полезную.

Ответ 4

Расширенный ответ: Перегрузка операторов - вот в чем дело. Операторы перегрузки - отличный вариант в С#, который позволяет удобство операторов вместо методов в классе.

При перегрузке оператора, такого как +, соответствующий сложный оператор присваивания также перегружен, например. +=

Как вы могли бы предположить, с их использованием, перегрузки операторов должны быть static и использовать ключевое слово operator, как в ответе @RoyiNamir.

Чтобы развернуть ответ, следующие операторы бинарного сравнения, помимо математических операторов, могут быть перегружены только парами:

  • == и !=
  • > и <
  • >= и <=

Что касается рекомендации по разработке кода, как сказал @RoyiNamir, в классе должны существовать перегрузки оператора, которые перегружают операторы.

Ответ 5

Создание собственных типов - хорошая идея; он предотвращает проблемы с помехами Марса, где вы добавляете килограммы и килограммы. Тем не менее, я предлагаю сделать их struct s, а не классы, поскольку это сделает их неизменными и удалит потенциал инициализации нулевых значений. Кроме того, сделайте value частным, чтобы вы могли делать такие вещи, как:

var startOfDay = new Megawatts(100);
var endOfDay = new Megawatts(65);
Megawatt result = startOfDay - endOfDay;

Вы также должны рассмотреть возможность реализации IComparable<>, IEquatable<>, операторов преобразования и т.д. Это позволит вам выполнять сравнения и строить коллекции, Megawatt s.

Выполнение всего этого - большая работа; обратитесь к С# Canonical Forms.