Как исказить встроенный тип в C#?

Таким образом в C++, я привык к способности сделать:

typedef int PeerId;

Это позволяет мне делать тип большим количеством самодокументирования, но дополнительно также позволяет мне заставлять PeerId представить другой тип в любое время, не изменяя весь код. Я мог даже превратить PeerId в класс, если бы я хотел. Этот вид расширяемости - то, что я хочу иметь в C#, однако я испытываю затруднения при выяснении, как создать псевдоним для 'интервала' в C#.

Я думаю, что могу использовать оператор использования, но он только имеет объем в текущем файле, которому я верю, так, чтобы не работал (Псевдоним должен быть доступным между несколькими файлами, не будучи переопределенным). Я также не могу получить класс из встроенных типов (но обычно это - то, что я сделал бы для искажения касательно типов, такие как Список или Словарь). Я не уверен, что я могу сделать. Какие-либо идеи?

16
задан void.pointer 15 July 2010 в 19:34
поделиться

4 ответа

Вы можете (ab)использовать неявные преобразования:

struct PeerId
{
    private int peer;

    public static implicit operator PeerId(int i)
    {
        return new PeerId {peer=i};
    }

    public static implicit operator int(PeerId p)
    {
        return p.peer;
    }
}

Это занимает столько же места, сколько int, и вы можете сделать:

PeerId p = 3;
int i = p;

Но я согласен, что вам это, вероятно, не нужно.

8
ответ дан 30 November 2019 в 16:09
поделиться

Вам нужно использовать полное имя типа, например:

using DWORD = System.Int32;
19
ответ дан 30 November 2019 в 16:09
поделиться

Резюме

Вот краткий ответ:

  • Typedef - это фактически переменная, используемая генераторами кода времени компиляции.
  • C # разрабатывается таким образом, чтобы избежать добавления языковых конструкций генерации кода.

Следовательно, концепция typedef не соответствует языку C #.

Длинный ответ

В C ++ это имеет больше смысла: C ++ начинался как прекомпилятор, который выдавал код C, который затем был скомпилирован. Это начало «генератора кода» по-прежнему влияет на современные возможности C ++ (т.е. шаблоны, по сути, представляют собой полный по Тьюрингу язык для генерации классов и функций во время компиляции). В этом контексте typedef имеет смысл, потому что это способ получить «результат» фабрики типов времени компиляции или «алгоритма», который «возвращает» тип.

В этом странном метаязыке (который освоили немногие за пределами Boost) typedef на самом деле является переменной.

То, что вы описываете, менее сложно, но вы по-прежнему пытаетесь использовать typedef в качестве переменной. В этом случае он используется как входная переменная. Поэтому, когда другой код использует typedef, он действительно не использует этот тип напрямую. Скорее, он действует как генератор кода времени компиляции, создавая классы и методы на основе входных переменных, определенных типом. Даже если вы проигнорируете шаблоны C ++ и просто посмотрите на определения типов C, эффект тот же.

C ++ и генеративное программирование

C ++ был разработан как многопарадиентный язык (объектно-ориентированный и процедурный, но не функциональный до появления Boost). Достаточно интересно, что у шаблонов появился неожиданный образ: генеративное программирование.(Генеративное программирование существовало до C ++, но C ++ сделал его популярным). Генеративные программы на самом деле являются метапрограммами, которые при компиляции генерируют необходимые классы и методы, которые, в свою очередь, компилируются в исполняемые файлы.

C # и генеративное программирование

Наши инструменты медленно развиваются в том же направлении. Конечно, Reflection emit можно использовать для «ручного» генеративного программирования, но это довольно болезненно. То, как поставщики LINQ используют деревья выражений, по своей природе очень генеративно. Шаблоны T4 очень близки, но все же не оправдывают ожиданий. «Компилятор как услуга», который, как мы надеемся, станет частью C # vNext, кажется наиболее многообещающим, если его можно комбинировать с какой-либо переменной типа (например, typedef).

Эта часть головоломки все еще отсутствует : ​​генеративным программам нужен какой-то автоматический механизм запуска (в C ++ это обрабатывается неявным созданием экземпляров шаблона ).

Однако явно не цель C # - иметь какой-либо «генератор кода» на языке C #, например шаблоны C ++ (вероятно, для простоты понимания; очень немногие программисты на C ++ понимают шаблоны C ++ ). Вероятно, это будет ниша, которую удовлетворит T4, а не C #.

Заключение (повторение Резюме)

Все вышесказанное говорит следующее:

  • Typedefs - это переменная, используемая генераторами кода.
  • C # разрабатывается таким образом, чтобы избежать добавления языковых конструкций генерации кода.

Следовательно, концепция typedef не соответствует языку C #.

12
ответ дан 30 November 2019 в 16:09
поделиться

Переопределение фундаментальных типов только ради изменения названия - это мышление C++ и не очень хорошо сочетается с более чистым объектно-ориентированным C#. Всякий раз, когда у вас возникает желание впихнуть концепцию из одного языка в другой, вы должны остановиться и подумать, имеет ли это смысл, и попытаться остаться родным для платформы.

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

1
ответ дан 30 November 2019 в 16:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: