Как псевдоним встроенного типа в С#?
Итак, в С++ я привык к возможности:
typedef int PeerId;
Это позволяет мне сделать тип более самодокументированным, но, кроме того, также позволяет мне сделать PeerId другим типом в любое время без изменения всего кода. Я мог бы даже превратить PeerId в класс, если бы захотел. Такая расширяемость - это то, что я хочу иметь в С#, однако мне трудно понять, как создать псевдоним для 'int' в С#.
Я думаю, что могу использовать оператор using, но он имеет только область видимости в текущем файле, который, как мне кажется, не работает (псевдоним должен быть доступен между несколькими файлами без переопределения). Я также не могу получить класс из встроенных типов (но, как правило, это то, что я сделал бы для псевдонимов ref-types, таких как List или Dictionary). Я не знаю, что я могу сделать. Любые идеи?
Ответы
Ответ 1
Вы можете (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;
Но я согласен, что вам это, вероятно, не нужно.
Ответ 2
Вам нужно использовать полное имя типа:
using DWORD = System.Int32;
Ответ 3
Резюме
Вот короткий ответ:
- Typedefs - это фактически переменная, используемая генераторами кода времени компиляции.
- С# разрабатывается так, чтобы не добавлять конструкторы языка генерации кода.
Таким образом, понятие typedefs не очень хорошо вписывается в язык С#.
Длинный ответ
В С++ это имеет смысл: С++ начал работать как прекомпилятор, который выплевывает C-код, который затем был скомпилирован. Это начало "генератора кода" все еще имеет эффекты в современных С++-функциях (т.е. Шаблоны по существу являются языком Turing для генерации классов и функций во время компиляции). В этом контексте typedef имеет смысл, потому что это способ получить "результат" типа времени компиляции factory или "алгоритм", который "возвращает" тип.
В этом странном метаязыке (который несколько за пределами Boost освоили), typedef на самом деле является переменной.
То, что вы описываете, менее сложно, но вы все еще пытаетесь использовать typedef как переменную. В этом случае он используется как входная переменная. Поэтому, когда другой код использует typedef, он действительно не использует этот тип напрямую. Скорее, он действует как генератор кода времени компиляции, строит классы и методы, основанные на входных переменных typedef. Даже если вы игнорируете шаблоны С++ и просто смотрите на C typedefs, эффект будет таким же.
С++ и Generative Programming
С++ был разработан как многопаразитный язык (OO и процедурный, но не функциональный, пока Boost не вышел). Интересно, что шаблоны развили неожиданный парадокс: генеративное программирование. (Генерирующее программирование было около С++, но С++ сделал его популярным). Генерирующие программы на самом деле являются метапрограммами, которые при компиляции генерируют необходимые классы и методы, которые в свою очередь компилируются в исполняемые файлы.
С# и генеративное программирование
Наши инструменты медленно развиваются в одном направлении. Конечно, излучение отражения может использоваться для "ручного" генеративного программирования, но это довольно болезненно. То, как поставщики LINQ используют деревья выражений, носит очень генеративный характер. Шаблоны T4 очень близки, но все еще не справляются. "Компилятор как служба", который, мы надеемся, будет частью С# vNext, представляется наиболее перспективным из всех, если его можно комбинировать с какой-то переменной типа (например, typedef).
Эта часть головоломки все еще отсутствует: генераторные программы нуждаются в каком-то автоматическом триггерном механизме (в С++ это обрабатывается неявным экземпляр шаблона).
Однако явно не цель С# иметь какой-либо "генератор кода" на языке С#, например С++-шаблоны (вероятно, для понимания, очень мало программистов на С++ понимают шаблоны С++). Вероятно, это будет ниша, удовлетворенная T4, а не С#.
Заключение (повторение сводки)
Все сказанное выше:
- Typedefs - это переменная, используемая генераторами кода.
- С# разрабатывается так, чтобы не добавлять конструкторы языка генерации кода.
Таким образом, понятие typedefs не очень хорошо вписывается в язык С#.
Ответ 4
Я также иногда чувствую, что мне нужны (целые) typedef для аналогичных целей для OP.
Если вы не возражаете против явных эксплойтов (я действительно хочу, чтобы они были), вы можете сделать это:
enum PeerId : int {};
Будет также работать для byte, sbyte, short, ushort, uint, long,
или ulong
(очевидно).
Непостоянное использование enum
, но оно работает.
Ответ 5
Переосмысление фундаментальных типов только ради изменения имени - это С++, и он не подходит для более чистого Object Orientated С#. Всякий раз, когда вы получаете желание обучать концепцию с одного языка на другой, вы должны остановиться и подумать, имеет ли это смысл и попытаться остаться родным на платформе.
Требование о возможности легкого изменения базового типа может быть удовлетворено путем определения вашего собственного типа значения. В сочетании с неявными операторами преобразования и арифметическими операторами вы можете определять очень мощные типы. Если вас беспокоит производительность для добавления слоев поверх простых типов, не делайте этого. 99% вероятность того, что этого не произойдет, и вероятность 1% заключается в том, что в случае, если это произойдет, это будет не "низкий висящий плод" оптимизации производительности.