Часто хочется абстрагироваться от простых типов и дать им имя. Т.е. например не int id, а MessageId id.
В C++ это typedef int MessageId
В Pascal это MessageId = int
А как это сделать в C#?
Использовать using не получится, т.к. это имя должно быть видно за пределами namespace и assembly... Т.е. чтобы пользователь класса мог писать MessageId, а не int...
Здравствуйте, csharpamateur, Вы писали:
C>А как это сделать в C#?
C>Использовать using не получится, т.к. это имя должно быть видно за пределами namespace и assembly... Т.е. чтобы пользователь класса мог писать MessageId, а не int...
Здравствуйте, Dr_Sh0ck, Вы писали:
D_S>Здравствуйте, csharpamateur, Вы писали:
C>>А как это сделать в C#?
C>>Использовать using не получится, т.к. это имя должно быть видно за пределами namespace и assembly... Т.е. чтобы пользователь класса мог писать MessageId, а не int...
D_S>через using можно назначить типу псевдоним
Псевдоним (alias) который назначается через using виден только внутри файла или namespace в котором он объявлен.
Здравствуйте, csharpamateur, Вы писали:
C>Псевдоним (alias) который назначается через using виден только внутри файла или namespace в котором он объявлен.
Как и сях, впрочем.
Другой вопрос, что там можно включать один файл в другой.
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, csharpamateur, Вы писали:
C>>Псевдоним (alias) который назначается через using виден только внутри файла или namespace в котором он объявлен.
L>Как и сях, впрочем. L>Другой вопрос, что там можно включать один файл в другой.
Точнее typedef то и размещается в .h, который потом везде и включается. Но все таки, что же делать в C#? Ведь это же не дело, если клиент должен будет писать int MessageId, а потом все переписывать, если мы поменяем int на long...
Кстати, а как красиво в C# обойти отсутствие вложенных функций? Т.е. если какая-то функция достаточно длинная, на Pascal можно ее легко разбить на вложенные подфункции и не передавать вручную рабочие данные (это делается автоматически передачей неявной ссылки на стек-фрейм вызывающей фукнции).
Можно конечно делать вложенный класс и затем делать (new WorkerClass(param1,param2)).DoTheWork()
А может как-то еще?
Здравствуйте, csharpamateur, Вы писали:
L>>Как и сях, впрочем. L>>Другой вопрос, что там можно включать один файл в другой.
C>Точнее typedef то и размещается в .h, который потом везде и включается. Но все таки, что же делать в C#? Ведь это же не дело, если клиент должен будет писать int MessageId, а потом все переписывать, если мы поменяем int на long...
C>Кстати, а как красиво в C# обойти отсутствие вложенных функций? Т.е. если какая-то функция достаточно длинная, на Pascal можно ее легко разбить на вложенные подфункции и не передавать вручную рабочие данные (это делается автоматически передачей неявной ссылки на стек-фрейм вызывающей фукнции).
Обычно таким массивные методы лучше выделить в отдельный класс. И проблема с передачей большого кол-ва параметров решится сама собой. Даже кажется есть какой-то патерн для этого дела.
C>Можно конечно делать вложенный класс и затем делать (new WorkerClass(param1,param2)).DoTheWork()
Это не поможет, т.к. стековые (локальные) переменные видны не будут.
C>А может как-то еще?
Здравствуйте, csharpamateur, Вы писали:
C>Часто хочется абстрагироваться от простых типов и дать им имя. Т.е. например не int id, а MessageId id.
В C# несколько другая философия. Если тебе хочется именно этого, то объяви новый класс MessageId
И у MessageId можно реализовать implicit typecast к int
Здравствуйте, Lloyd, Вы писали:
L>Обычно таким массивные методы лучше выделить в отдельный класс. И проблема с передачей большого кол-ва параметров решится сама собой. Даже кажется есть какой-то патерн для этого дела.
C>>Можно конечно делать вложенный класс и затем делать (new WorkerClass(param1,param2)).DoTheWork()
L>Это не поможет, т.к. стековые (локальные) переменные видны не будут.
Собственно WorkerClass в данном случае и есть отдельный класс для метода, т.е. мы всю функцию переносим в DoTheWork
А подфункции вообще часто применяются без использования переменных вызывающей функции. Просто для того, чтобы сделать код легче и не забивать интерфейс класса не нужными функциями, которые выполняют промежуточную техническую работу.
Здравствуйте, WarlockOnLine, Вы писали:
WOL>Здравствуйте, csharpamateur, Вы писали:
C>>Часто хочется абстрагироваться от простых типов и дать им имя. Т.е. например не int id, а MessageId id.
WOL>В C# несколько другая философия. Если тебе хочется именно этого, то объяви новый класс MessageId WOL>И у MessageId можно реализовать implicit typecast к int
Интересный в принципе вариант. Можно делать struct'ы содержащие эти типы. Однако если для простых типов boxing случается не всегда, то для struct к примеру конструктор будет вызываться всегда и implicit преобразование — это тоже код который будет вызываться. Т.е. лишний оверхед на пустом месте.
Здравствуйте, csharpamateur, Вы писали:
C>Интересный в принципе вариант. Можно делать struct'ы содержащие эти типы. Однако если для простых типов boxing случается не всегда, то для struct к примеру конструктор будет вызываться всегда и implicit преобразование — это тоже код который будет вызываться. Т.е. лишний оверхед на пустом месте.
Можно попробовать изменить архитектуру приложения и совсем отказаться от int'овских MessageId'ов
Например, сделать класс и объявить там readonly свойство Id. Кто-то уже на форуме измерял производительность обращения к полю и к get-свойству, возвращающему поле: получилось примерно одинаково
WOL>Например, сделать класс и объявить там readonly свойство Id. Кто-то уже на форуме измерял производительность обращения к полю и к get-свойству, возвращающему поле: получилось примерно одинаково
К сожалению get тормозят, правда совсем немного, но до инлайн не дотягивают.
И для ускорения правда на критичных алгоритмах простой инлайн дает 10-20% прирост скорости.
Для нормальных приложений это сущий пустяк, а для тестов и просто борьбы за скорость много.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, csharpamateur, Вы писали:
C>Но хотелось бы использовать к примеру FileSize вместо long...
Зачем? Неужели для того, чтобы одним махом менять long на int? Такие типы я прошиваю в программах. В более сложных случаях, имхо следует использовать классы
Здравствуйте, csharpamateur, Вы писали:
C>Однако если для простых типов boxing случается не всегда, то для struct к примеру конструктор будет вызываться всегда и implicit преобразование
Можно пример ситуации когда простой тип бокситься не будет, а структура будет?
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, csharpamateur, Вы писали:
C>>Однако если для простых типов boxing случается не всегда, то для struct к примеру конструктор будет вызываться всегда и implicit преобразование
AVK>Можно пример ситуации когда простой тип бокситься не будет, а структура будет?
Скажем так при вызове метода Proc(int a) и Proc(SomeStruct a), во втором случае для передачи значения типа int придется еще вызвать конструктор для SomeStruct. А при использовании a будут добавляться вызовы преобразования в int...
Здравствуйте, csharpamateur, Вы писали:
C>>>Однако если для простых типов boxing случается не всегда, то для struct к примеру конструктор будет вызываться всегда и implicit преобразование
AVK>>Можно пример ситуации когда простой тип бокситься не будет, а структура будет?
C>Скажем так при вызове метода Proc(int a) и Proc(SomeStruct a), во втором случае для передачи значения типа int придется еще вызвать конструктор для SomeStruct. А при использовании a будут добавляться вызовы преобразования в int...
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, csharpamateur, Вы писали:
C>>>>Однако если для простых типов boxing случается не всегда, то для struct к примеру конструктор будет вызываться всегда и implicit преобразование
AVK>>>Можно пример ситуации когда простой тип бокситься не будет, а структура будет?
C>>Скажем так при вызове метода Proc(int a) и Proc(SomeStruct a), во втором случае для передачи значения типа int придется еще вызвать конструктор для SomeStruct. А при использовании a будут добавляться вызовы преобразования в int...
AVK>А боксинг то где будет?
Я про боксинг для структур не говорил. Я имел в виду boxing как дополнительную операцию, подобную вызову конструктора или оператора приведения типа для структуры.
Здравствуйте, csharpamateur, Вы писали:
L>>Это не поможет, т.к. стековые (локальные) переменные видны не будут.
C>Собственно WorkerClass в данном случае и есть отдельный класс для метода, т.е. мы всю функцию переносим в DoTheWork C>А подфункции вообще часто применяются без использования переменных вызывающей функции. Просто для того, чтобы сделать код легче и не забивать интерфейс класса не нужными функциями, которые выполняют промежуточную техническую работу.
Вообще-то интерфейсом класса называют его публичные методы, так что если ты не хочешь забивать интерфейс -- не забивай. Делай "не нужные" функции приватными и все.