C #: методы / конструкторы с одинаковыми сигнатурами и именованные аргументы - PullRequest
2 голосов
/ 25 февраля 2012

Предположим, например, что я определяю класс Complex для представления комплексных чисел. Я хотел бы определить два конструктора, чтобы я мог написать, например:

Complex z1 = new Complex(x: 4, y: 3);
Complex z2 = new Complex(r: 2, theta: Math.PI / 4);

Однако я не могу определить конструкторы следующим образом:

public Complex(double x, double y) { ... }
public Complex(double r, double theta) { ... }

потому что оба конструктора будут иметь одинаковую подпись, что недопустимо. Но в C # 4 я могу написать это, используя необязательный аргумент:

public Complex(double x, double y) { ... }
public Complex(double r, double theta, bool unused=true) { ... }

Это работает, я могу использовать указанные выше вызовы конструктора, как и предполагалось. Единственная цель аргумента unused - сделать подписи разными; он полностью не используется, как при определении, так и при вызове конструктора.

Мне кажется, это уродливый трюк: есть ли лучший вариант?

Ответы [ 3 ]

7 голосов
/ 25 февраля 2012

Сделать конструктор частным и иметь статическую функцию фабричного стиля.

public static Complex CreateComplexPolar(double r, double theta);
public static Complex CreateComplex(double x, double y);

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

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

public struct PolarCoordinates
{
  public double Rho;
  public double Theta;
}

public struct CartesianCoordinates
{
  public double X;
  public double Y;
}

public Complex(PolarCoordinates pc);
public Complex(CartesianCoordinates cc);
3 голосов
/ 25 февраля 2012

Создайте статический метод для создания класса, скажем, Complex::FromDouble и Complex::FromDoubleAndTheta.

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

Например, см. TimeSpan FromDays и FromHours .

ps Используйте лучшие имена:)

HTH

0 голосов
/ 25 февраля 2012

Единственное, о чем я могу думать, это сделать один конструктор (double, double), а другой может быть double, Func.

public Complex(double x, double y) { ... }
public Complex(double r, Func<double> theta) { ... }

В вашем примере сверху выглядитвыполнение вычисления, и результатом этого вычисления является 2-е значение для этого конструктора.Если это всегда так, тогда вы можете просто сделать его параметром Func.Вроде хак, но это может быть лучше, чем иметь необязательный третий параметр, который ничего не делает.

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