эквивалент typedef для перегрузки в c # - PullRequest
0 голосов
/ 18 февраля 2009

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

Например

int a; // takes role A
int b; // takes role B

var A = new Foo(a);  // should call one constructor
var B = new Foo(b);  // should call another constructor

Теперь ясно, что это не сработает, но если бы я мог определить тип (не просто псевдоним), который во всех именах будет int, кроме имени:

typedef int TypeA;  // stealing the C syntax
typedef int TypeB;

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

Есть ли способ обойтись без class или struct обёрток, чтобы сделать это в c #?


Было бы неплохо, если бы решение также работало для чисел с плавающей и двойной чисел.

Ответы [ 4 ]

13 голосов
/ 18 февраля 2009

Нет прямого эквивалента typedef, но вы можете сделать следующее:

using TypeA = int;
using TypeB = int;

Однако это просто псевдоним типа, а не создание нового сильного типа. Поэтому компилятор все равно будет обращаться с ними как int при разрешении вызовов методов.

Лучшим решением может быть создание простых классов-оболочек, которые обертывают int и обеспечивают неявное приведение типа, например:

struct TypeA
{
   public TypeA(int value)
   {
      this.realValue = value;
   }

   private int realValue;
   public static implicit operator int(TypeA value)
   {
     return this.realValue;
   }

   public static implicit operator TypeA(int value)
   {
     return new TypeA(value);
   }
}

Однако, в большинстве ситуаций, enum будет более подходящим.

6 голосов
/ 18 февраля 2009

Это может быть далеко, но не могли бы вы использовать enum для этого? База перечислений int, но она типизирована, и вы можете определить различные конструкторы в зависимости от типа переданного перечисления.

2 голосов
/ 18 февраля 2009

Если это только для конструктора, не могли бы вы использовать что-то вроде этого:

 int dom = 5;
int doy = 100;

Foo b = Foo.NewFromDayoftheMonth(dom);

Foo c = Foo.NewFromDayoftheYear(doy);

где каждый метод является статическим и создает новый объект Foo на основе переданных параметров.

Мне кажется, что это решение, где больше ничего нет.

0 голосов
/ 19 февраля 2009

Я бы также создал структуру вокруг значения:

public struct TypeA
{
  private int value;
  public TypeA(int value)
  {
    this.value = value;
  }

  public static explicit operator int(TypeA a)
  {
     return a.value;
  }

  public static explicit operator TypeA(int value)
  {
     return new TypeA(value);
  }
}

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

Тип Year может предоставлять свойство IsLeap, день месяца может ограничиваться значениями от 1 до 31 и предоставлять специальную арифметику.

...