Как сделать 3 конструктора с одинаковой сигнатурой?

1,00
р.
Нужно написать программу, содержащую класс Triangle. В данном классе должно быть три конструктора:
Конструктор, принимающий три стороны. Конструктор, принимающий две стороны и угол между ними и рассчитывающий третью сторону по теореме косинусов. Конструктор, принимающий два угла и сторону между ними и рассчитывающий оставшиеся стороны по теореме синусов (памятуя о теореме о сумме углов треугольника).
Каждый Triangle также должен возвращать собственную площадь.
То есть имеем следующее:
class Triangle { Triangle(double side1, double side2, double side3) { } Triangle(double side1, double side2, double angle) { } Triangle(double side1, double angle1, double angle2) { } }
Вся проблема в том, что у всех трех конструкторов одинаковая сигнатура, но разная логика. Вопрос: как решить эту проблему "правильно"?
"Неправильные" варианты:
Замена параметра(ов) double на string и дальнейший парсинг string в double. Замена параметра(ов) double на float. Вынесение параметров в массив: Triangle(double[] sides, double angle)
Создание нового типа данных Angle.

Ответ
Вариант 1 - используйте именованные конструкторы.
Именованным конструктором называется статический метод, задача которого - создать объект с заданными параметрами. Иногда их еще не вполне корректно называют фабричными методами.
class Triangle { private Triangle() {}
public static Triangle From3Sides(double side1, double side2, double side3) { ... }
public static Triangle From2SidesAndAngle(double side1, double side2, double angle) { ... }
public static Triangle FromSideAnd2Angles(double side, double angle1, double angle2) { ... } }
Вариант 2 - использовать доменные типы данных
Определяем типы данных "длина" и "угол" - и используем их в конструкторах.
class Length { public double Value { get }
public Length() {} public Length(double value) { Value = value }
public static implicit operator double (Length length) => length.Value public static implicit operator Length (double value) => new Length(value) }
class Angle { public double Value { get }
public Angle() {} public Angle(double value) { Value = value }
public static implicit operator double (Angle angle) => angle.Value public static implicit operator Angle (double value) => new Angle(value) }