2009-02-18 4 views
0

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

Например

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#?


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

ответ

13

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

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 будет более подходящим.

+0

это как структура и без неявного кастинга - это то, что я делал. Это работает хорошо. – BCS

+0

Есть ли штраф за исполнение для этого или компиляторы C#, достаточные для оптимизации оболочки? Я пропускаю что-то, что эквивалентно новому типу Haskell в C# (они суть то, что вы только что сделали, но стираются во время компиляции (но после проверки типов)). – FunctorSalad

+0

Я не знаю, будет ли значительная часть штрафа за исполнение или нет. Боюсь, вам придется попробовать и посмотреть. –

6

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

+0

Это будет работать (+1) для случаев, когда разрешен только небольшой диапазон (месяц-год), но в других случаях (году), которые вы начали бы взломать, чтобы сделать значения C# allow, которые иначе не определены. – BCS

+0

в C# int.Max не совсем мал; -p –

+0

IIRC C# ограничивает, как вы можете установить тип перечисления, чтобы он имел только определенное значение. Так что задано «enum E {V = 1} E e;" e не может принимать значение 2 без какого-либо взлома. – BCS

2

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

int dom = 5; 
int doy = 100; 

Foo b = Foo.NewFromDayoftheMonth(dom); 

Foo c = Foo.NewFromDayoftheYear(doy); 

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

Этот Кажется, это решение для меня, где нет ничего другого.

+0

Это один из вариантов, который я рассмотрел, но я хочу, чтобы компилятор меня проверял. См. Мое предстоящее редактирование – BCS

0

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

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.

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